Search

Geek Girl Joy

PHP, HTML & CSS – Magic 8 Ball

wp-1488672581812.png
Magic 8 Ball is a browser based implementation of a “Magic 8 Ball“. This project features autoloading PHP classes, HTML and CSS to create a virtual 8 Ball that will soon become your goto oracle with all important questions in your life!

You can preview a running version of this project here: Magic 8 Ball

Every now and then I like to post a complete project for you all to enjoy and often times that means it’s just a simple proof of concept example rather a full featured project. The Magic 8 Ball project is completely functional but there isn’t anything really fancy like animation or a neural network at work in this project, however I have a great set of tutorials on neural networks here: Getting Started With Neural Networks… if you’d prefer to read about that topic instead. πŸ™‚

The origins of this project was I was looking for “spooky” and fun projects or code to work on/blog about during the Halloween 2016 season but ultimately I didn’t post this project.

Despite not posting it on my blog at that time, I uploaded it to my github account because liked how this project turned out so recently I thought I would blow the dust off and show it to you.

If you just want to dig in and start playing with the code, you can access everything for this project on my github: https://github.com/geekgirljoy/PHP/tree/master/Projects/magic-8-ball or copy the code segments below into the correct files.

Otherwise the tutorial starts now πŸ˜‰

There is a caveate with this project, for simplicity/speed I used Bootstrap to reduce the CSS I had to write but you could eliminate that from the project very easily if you want to rely entirely on your own grid system and CSS.

Folder Structure

Setting up the folders for this project is very straight forward, .css files in the [css] folder and .php files (other than index.php) in the [php] folder.

Inside the [php] folder there is a sub-folder called [classes] where the class files for the project will reside.


[magic-8-ball]
             β”œβ”€β”€ index.php
             └── [css]
             β”‚       └── magic-8-ball.css
             └── [php]
                     β”œβ”€β”€ Magic8Ball.php
                     └── [classes]
                                 └── Magic8Ball.class.php

index.php

Our Index file creates the framework for the Magic 8 Ball. We link to all the CSS used by the project including Bootstrap and JQuery.

Inside the body of the page we create a form with with a text input field along with a submit input. The form uses GET so the ‘Question’ field will be accessible in the URL however if you would prefer to use the POST method all you need to do is change method attribute on the form from GET to POST as the PHP code uses $_REQUEST[‘Question’] so it will work however you need for your situation

Beneath the form we include Magic8Ball.php on the page by doing <?php include('php/Magic8Ball.php'); ?>.


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>Magic 8 Ball</title>
        <script src="https://code.jquery.com/jquery.min.js"></script>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
        <link href="https://fonts.googleapis.com/css?family=Creepster" rel="stylesheet">
        <link href="css/magic-8-ball.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12 text-center">
                <h1>Magic 8 Ball</h1>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <div class="row">
                        <div class="col-md-12 text-center">        
                            <form action='#' method='get'>
                                <input name='Question' placeholder="Ask a question..." />
                                <input class='btn btn-success' type='submit' value='Ask' />
                            </form>
                        </div>
                    </div>
                    <br>
                    <div class="row">
                        <div class="col-sm-4 col-md-4 col-lg-5"></div>
                            <div class="col-sm-4 col-md-4 col-lg-4">
                            
                                <?php include('php/Magic8Ball.php'); ?>
                            
                            </div>
                        <div class="col-sm-4 col-md-4 col-lg-3"></div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

 

magic-8-ball.css

The CSS is all pretty straight forward, nothing unusual here. πŸ™‚


body{ 
    background-color:#444444; 
} 

h1{ 
    font-family: 'Creepster', cursive; 
    color:#00bb00; 
} 

#eight{ 
    font-size:400%; 
    color: #000000; 
}
 
.black-ball{
    border-radius: 50%; 
    background-color: #000; 
    width: 200px; 
    height: 200px; 
    display:table; 
    text-align:center; 
    padding: 50px; 
    box-shadow: 5px 5px 5px #333333; 
} 

.white-ball{ 
    border-radius: 50%; 
    background-color: #fff; 
    width: 22%; 
    height: 22%; 
    display:table-cell; 
    vertical-align:middle; 
    font-family: 'Creepster', cursive; 
}

.answer{ 
    color: #bb0000; 
}

 

Magic8Ball.php

The PHP code that generates the 8 Ball is pretty simple. We start by setting up an auto-loader to auto include all classes we put in our classes subfolder.

Note: In order for your classes to get auto loaded by the code as written you will need to name the class file using this naming convention: <Class or File Name>.class.php If you would prefer not to use that naming convention you can modify the auto-loader to meet your needs.

We follow that up with the Div tags that become the body of the 8 Ball when styled with our CSS.

After that we use $_REQUEST[‘Question’] to check if the user has asked a question. If no question was asked the #8 placeholder is used.

Once the user asks a question we create an array of strings containing of all possible responses which we call $answers.

After that we instantiate the Eight Ball object by passing the class the count of how many items are in our $answers array using: $EightBall = new Magic8Ball(count($answers)-1);. The class will return a number as it’s answer.

Once we have the $EightBall answer all we need to do is echo the the result in a span assigned the ‘answer’ class: echo ‘<span class=”answer”>’ . $answers[ $EightBall>answer ] . ‘</span>’ . PHP_EOL;.



<?php
    function ClassAutoloader($class) {
        include 'php/classes/' . $class . '.class.php';
    }
    spl_autoload_register('ClassAutoloader');
?>
<div class="black-ball">
                                <div class="white-ball">
                                    <?php
                                    if(isset($_REQUEST['Question'])){
                                        
                                    $answers = array("It is certain",
                                        "It is decidedly so",
                                        "Without a doubt",
                                        "Yes, definitely",
                                        "You may rely on it",
                                        "As I see it, yes",
                                        "Most likely",
                                        "Outlook good",
                                        "Yes",
                                        "Signs point to yes",
                                        "Reply hazy try again",
                                        "Ask again later",
                                        "Better not tell you now",
                                        "Cannot predict now",
                                        "Concentrate and ask again",
                                        "Don't count on it",
                                        "My reply is no",
                                        "My sources say no",
                                        "Outlook not so good",
                                        "Very doubtful");
                                        
                                        /*
                                        *    Invoke the wisdom of the Magic 8 Ball.
                                         *
                                        *    Oh great magic eight ball. We beseach thee to answer our question :-P
                                         *   Display the answer.
                                        */
                                        $EightBall = new Magic8Ball(count($answers)-1);
                                        echo '<span class="answer">' . $answers[ $EightBall->answer ] . '</span>' . PHP_EOL;
                                    }
                                    else{
                                        // Initial value of of the ball
                                        echo'<div id="eight">8</div>' . PHP_EOL;
                                    }
                                    ?>
                                </div>
</div>

 

Magic8Ball.class.php

The class file defines the Magic 8 Ball. It has a single property ‘$answer’ and a single method (the constructor). When the class is instantiated, it takes a single argument ($total) which it uses as the $max value for mt_rand().



<?php
/*
*    Magic8Ball.class.php
 *
*    Joy Harvel
 *
*    09/18/2016
 *
*/
class Magic8Ball{
	public $answer;
    function __construct($total) {
        $this->answer = mt_rand( 0 , $total);
    }
}
?>

If you have gotten this far all that is left to do is test the code and get top notch advice on all your tough questions! πŸ˜›

Live Preview: Magic 8 Ball

View Source: Magic 8 Ball on Github

As always I hope you found this post and project both interesting and informative. Please Like, Comment & share this post with your friends and followers on your social media platforms and don’t forget to click the follow button over on the top right of this page to get notified when I post something new.

Notice: I am seeking paid sponsors for my content so if you would like to sponsor my work please contact me.

Much Love,
~Joy

My old posts

You may have noticed a flood of content posted to my blog in the past couple of days. These are all my posts from JoyHarvel.com please enjoy them and I look forward to bringing even more and greater works going forward.

Much Love,

~Joy

PHP Mobile App Development

Before I begin, shout out to all my regular readers! Thanks for all your warm wishes and concern over my expired domain, you know who you are… πŸ˜‰

Also, a quick update on my family for those who are interested, Xavier Logich (my infant son) was born 02/04/17 at 12:05 in the afternoon via an unplanned Caesarean weighing exactly 8 Lbs. (3.62874 Kg. for my readers who use metric) and we are doing well.

My Little Logich

20170212_152139
Xavier Logich

Why a name like Logich? Because it is a reminder that no matter what, if he thinks things through he can do anything! πŸ™‚

Okay, enough about my personal life lets talk about PHP Mobile App Development!

To start, if you are PHP programmer, you have essentially been excluded from client side development for years. PHP can and does power many cloud based apps (all or in part) but was never available as a client side language. Get ready for that to change!

The Internet’s favorite language ( VERY debatable I know πŸ˜› ) is coming to mobile devices.

I previously blogged about Server for PHP which creates a server for PHP on an Android device. Couple that with MariaDB Server by the same developer and you have a nice package for running PHP code directly from your Android phone or tablet. That’s great for learning to code PHP on a mobile device as well as for hobbyists looking to do something fairly quick / something for your own use.

However this isn’t a really great option for developing mobile apps that you intend to sell, and lets face it… you like to code, but you are also trying to pay the bills!

Here is where the magic of KikAppTools comes in.

Obligatory disclaimer: I am not affiliated, employed or sponsored byΒ KikAppTools (or anyone for that matter) however I am seeking paid sponsors for my content so if you would like to sponsor my work please contact me or support me on Patreon.

KikAppTools lets you write PHP code that compiles down to a native mobile app. The dev tools are cross platform and they include an Eclipse-based plugin should you want that though it’s not required, notepad/nano/vim will work just fine for all you old school hardcore unhinted coders. πŸ˜›

Why KikAppTools? If you are a PHP indi developer or a small group/team/startup that relies on PHP then KikAppTools lets you stick with PHP on mobile projects and leverage your existing team of skilled PHP programmers rather than having to outsource the mobile development portion of your project or hiring additional programmers skilled in native mobile development.

Pros:

  • PHP from start to finish, leverage your existing dev team on entirely new or larger projects.
  • It’s FREE, even for commercial applications.
  • You own the app, no sublicencing of your code.
  • The dev’s are a small but skilledΒ group of programmers who are very responsive to feedback and are desperate for alpha/beta testers so if you run into trouble they are happy and motivated to help solve your problem (But do them a favor,Β  check the help forums first so you don’t overwhelm them with the same 5 questions).
  • Their Github account has working demo application code.
  • They have a “showcase” page for apps built using KikAppTools so it’s like getting free advertising for your startup or app!

Cons:

  • It’s “bleeding edge” new (read that as in active development) so there are no guarantees that there wont be occasional bugs while they continue to develop.
  • Command Line Compiler/Build tool. Currently there is NO GUI interface so it’s not exactly the most “user friendly” interface and the menu system could be simplified in my opinion.
  • No auto update system (but they will email you when an update is available).
  • Requires native SDK build tools to be installed. At its core, KikAppTools is a PHP to Objective-C (iOS) or Java (Android) transpiler and Builder so even though it will auto build your app you will still need to install the iOS & Android SDKs.
  • Small (but growing) community.

If you have any interest in mobile app development and PHP do yourself a favor and at least keep it on your radar as the developers seem to be making tons of progress!

Further, although its currently free because they they are focusing on making a great product first and will worry about monetization strategies second, in their FAQs section they say they are:

“contemplating accessible licenses for developers (Indie/Business/Enterprise – paid monthly or annually) depending on the features”Β 

I am sure plenty of PHP developers will have no problem paying for this service, however, Speaking more to the developers here… These days there are a lot of options for creating mobile apps (some of which cost nothing) that I think it would artificially suppress adoption (even by motivated PHP programmers) simply because there is a barrier to adoption.

I think Unity3D has a great use license that encourages student developers to work with it for free and even lets indi developers make some money before it costs them anything.

My 2 cents is that KikAppTools could have a similar license where lone developers or small teams can make up to some value for free every year and after which a “pro” or better license would need to be obtained if more than a few seats or more than some level of profit from the app. This would encourage developers to give it a try while also getting them to stick around and actually use it. Further,Β  it guarantees that as KikAppTools use grows the developers profit will grow as well.

And with that, this post is starting to get long…

Much Love,

~Joy

 

 

 

 

I’m Back…

I’m Back… well sort of.

If you haven’t noticed… JoyHarvel.com is no more but hopefully that is only a temporary set back.

Many of you know that I have a baby on the wayΒ  (any day now) and because my site was not generating a self sustaining level of income I could not justify the cost of renewing right now.

I have setup shop on the free hosting space that WordPress.com so graciously makes available and will showcase my work from here going forward for the foreseeable future so please open this link https://geekgirljoy.wordpress.comΒ  and bookmark it. Remember you can also find me on Twitter and Github.

When my efforts begin generating profit again I will either upgrade to a paid WordPress account with more backend control or more likely shop around for robust Virtual Private Server hosting.

Previously I was on GoDaddy and I am not opposed to returning, they really do have a great service, however they upset me a little last year by saying that they offer SSH (shell/terminal connectivity to your domain/server) however it turned out that it lacked Sudo (admin privileges) so… really what’s the point of offering it?? But I digress, they informed me the only way they would grant admin control would be for me to do a paid upgrade to VPS hosting. I get that they are in business and trying to turn a profit, so am I and to be honest, if I had the spare cash I would have upgraded then and there but I didn’t and my frustration was compounded by the fact that they would not install any PHP extensions on my behalf.

To be clear, I wasn’t asking for something wild (IMHO) I simply had a bunch of web based AI projects lined up, that were based on the FANN library which is easy enough for a server tech to install in their spare time.

Frankly, I just find it odd that a large professional web host like GoDaddy that is seemingly heavily invested in PHP doesn’t include the popular, free and easily accessible FANN PHP extension in their standard server image… HINT HINT GoDaddy, you can find it here: https://github.com/bukka/php-fann

Anyway, the PHP AI projects are on hold for now but I am starting to look into alternative venues to showcase my work in that regard.

As for my computer situation that I previously blogged about. My best friend took pity on me and upgraded his families computers and let me pick apart the remains to build a functional development computer! I can now run all my dev tools (which I will blog about separately) so things are looking up! πŸ™‚

Its a new year and I am hoping we can do some amazing things!

Much Love,

~Joy

Can you ditch your desktop for an Android touch device?

My conclusion, in some cases maybe… read on!

First, let me say that I am not paid for any of my posts… and that is absolutely horrible! However, with your help we can change that!

πŸ˜›

If you are interested in sponsoring my site and all the FREE content I create, like this blog or all the code on my github profile for instance please contact me! Don’t see anything you like? Make a suggestion! Think of me as your developer! πŸ˜‰

You may be aware that my computer died recently… and my development system is a bit underwhelming and I recently upgraded my phone to a new Samsung Galaxy 7 Edge and ended up reducing my monthly phone bill so win/win and I have started looking at how it can alter and improve my current workflow.

Mainly the primary drawback to using a touch interface device (in this case an Android phone) to work from has been that while they excel at consuming information e.g. playing games, reading news, clicking and scrolling on apps… and since this is a phone we can add making phone calls to the list, they are not very good with rapid input and manipulation of information and generally lack ‘precision’. Precision can largely be solved by using a quality fine tipped stylus (like this), or with the use of a bluetooth mouse (like this) if you need the highest level of precision. You can even add a keyboard (like this) or on the cheaper (but functional) end of the spectrum (like this).

Additionally, screen space is at a premium on touch devices and it’s been difficult to create intuitive and comfortable UI’s which helped lead to the stripped down and simplified appearance of UI’s we see today, a sad trend in my opinion because processing power is at an all time high, but i digress… google Skeuomorphism web design for a bunch of articles from 2013 about how “flat UI is here to stay”…well… with that striped down appearance has come less complexity, sometimes that means easier to use and sometimes that just means less useful. πŸ˜‰

Predominantly programmers don’t need complex interfaces to operate and are mainly reading & writing code so… if you allow for decent enough input devices and sufficient on device tools a programmer could conceivably use an android phone or tablet to work!

Do the right tools exist?

While the offerings are still growing, I found a few gems and rather than cover each one in depth at this time, I will just briefly highlight a few that I hope you will really enjoy!

Python native on your phone

Code and run Python scripts (console & web apps) natively on your Android!

Using the S4AL (Scripting Layer for Android) you can even automate things like taking pictures, you can build GUI’s and get access to device sensor data, do text/string to speech etc…

https://play.google.com/store/apps/details?id=org.qpython.qpy3&hl=en

Here is “Hello World” text to speech in python:

import sl4a
droid = sl4a.Android();
droid.ttsSpeak('Hello World');

I am having such a fun time playing with this and finding ways to use it!… if you are into Cross Platform Development, Automation, Data Science and AI you NEED to give QPython a try! Want to make games? Add pygame. Want to do cross platform gui applications? Use kivy. The possibilities seem endless!

PHP native on your phone

https://play.google.com/store/apps/details?id=com.esminis.server.php

A robust full featured Apache server this is not! But this is a PHP web server running natively on your android device… really let that sink in… you’re welcome!

πŸ˜‰

But… what good would PHP be without a database? Well, now you can run databases natively on your phone (HOW AWESOME IS THIS?!!!!)

Maria (MySQL): https://play.google.com/store/apps/details?id=com.esminis.server.mariadb&hl=en

Yes you can install PHPMyAdmin πŸ˜‰

MongoDB: https://play.google.com/store/apps/details?id=com.esminis.server.mongodb

Now, a tablet would probably be better than a phone just due to screen space and potentially better specs but this latest crop of phones are more than capable of running these development apps and I expect to see full stack and fully integrated AAMP/ANME (Android, Apache/Node, MySQL/Mongo, PHP/Python, Express (or other) ) servers in the not to distant future and the hardware to run them too!

But, there’s more!!! Want a traditional “start” menu? It’s safe to assume that SOMEBODY would want that, and why not if you are using a keyboard and mouse?

Well, your prayers are answered in the app called Andromium OS

https://play.google.com/store/apps/details?id=com.andromium.os

Are these apps everything you’d need to ditch the PC? Maybe, maybe not but I feel confident in saying the overwhelming trend seems to be that given time you will be able to have a single powerful touch device you use as a phone while on the go and as a powerful workstation via use of a docking station or wireless peripheral connectivity, to add a larger screen and additional input devices when sitting down to get work done.

Much Love,

~Joy

Where have I been?

To anyone actually following my blog and wondering where I have been and why I haven’t been posting, yes, the rumors were true…I was abducted by aliens!

πŸ˜›

LOL, actually my laptop died and sourcing new hardware was a bit of a challenge. 😦

As it stands I am now running an old Dell DC7600 32 Bit CPU & 2 GB of Ram… Well beggars can’t be choosers and at the moment it’s the best I can do, I’m grateful it runs.

I am running my FAVORITE Linux Distro (Mint).

Before my laptop died I had been starting to shift my work focus to using tools like Unity3D to make games and mobile apps and not just doing web stuff with PHP (still using PHP but working on other projects and with tools too) however neither Unity3D (Javascript & C#) nor Unreal Engine (C++) will operate on a 32 bit operating system and not one with such low specs so that was a bit of a bummer…

On the upside I was pleasantly surprised to see that Blender (Logic Blocks & Python) works just fine! πŸ™‚

I normally work in Blender for modeling items for 3D printing (I have designed a few products that I hope to show you guys in the next few months) and creating assets to play with in Unity3D. I was aware that Blender had a gaming engine but I had never tried it before. Having worked with the BGE (Blender Game Engine) a little I discovered it was actually a lot easier and faster to rig up a functional game in blender than I had thought! In fact I really recommend that you give it a try for yourself!

If you want a great tutorial on using the BGE to make a game head over to BornCG’s channel on Youtube for an excellent set of tutorials.

Here’s one to get you started but I really recommend you head over to you Youtube and subscribe to the BornCG channel!

Much Love,

~Joy

Spooky Coding Convention

We’ve all seen code that is just plain scary because of how bad it is!

πŸ˜›

However, have you ever considered a ‘Spooky’ code standard/convention?

Halloween is on it’s way and you may be looking for a little something extra to help you get into the spirit (or should I say poltergeist, banshee, ghoul?) of the holiday so may I suggest for the duration of October, instead of using the placeholdersFOO‘ & ‘BAR‘ in your code you can use ‘BOO’ and ‘EEEK’.

PHP Example

<?php
$boo = 'eeek!';
?>

JavaScript Example

var boo = 'eeek!';

 

C++/C# Example

string boo = "eeek!";

 

If you have any suggestions as to other ‘Spooky Coding Conventions’ we can all use go ahead and submit them in the Leave a Reply section below or tweet them at me using the hashtag #SpookyCoding and I will post the best ones with credit going to the poster in a followup article.

Keep in mind it’s best if your suggestions are ‘cross language’ as much as possible so that everyone can join in the fun but if it’s not and it’s particularly spooky it might get included anyway. πŸ˜‰

Much Love,

~Joy

Halloween is coming to the web

Halloween is coming so let’s make it the spookiest ever! To make your projects and posts a graveyard smash, consider using the following Emoji / Unicode Characters. πŸ™‚

CSS

 

<style> span{font-size:50px;} </style>

 

Jack o’Lantern

<span>πŸŽƒ</span>
Default Unicode

 

pumpkin-unicode

WordPress

πŸŽƒ


 

Ghost

<span>πŸ‘»</span>
Default Unicode

ghost-unicode

WordPress

πŸ‘»


 

Skull

<span>πŸ’€</span>
Default Unicode

skull-unicode

WordPress

πŸ’€

 


 

Knife

<span>πŸ”ͺ</span>
Default Unicode

knife-unicode

WordPress

πŸ”ͺ

 


 

Horned Face

<span>😈</span>
Default Unicode

horned-face-unicode

WordPress

😈

@import url(‘https://fonts.googleapis.com/css?family=Creepster&#8217;);

Now go out there and code something…

Spooky!

Much Love,

~Joy

Pathfinding From Scratch using a Neural Network

First, the goal of this post is to get you working with a pathfinding neural network as quickly as possible. The best way to learn is to start doing and by the end of this tutorial you WILL have a working pathfinder! While this example uses PHP as the coding language, FANN is available for over 20 languages so you should have little trouble adapting this tutorial to work with your favorite language.

If you are following along with this tutorial, there are a couple of obligatory disclaimers… πŸ˜›

  1. You will need to setup a test environment with PHP and the FANN library. I have a tutorial on that here: Getting started with Neural Networks
    Note: The Official PHP FANN repo on Gitub agreed to include this as an official example so when you download or clone the PHP FANN repo the Pathfinder example will already be included for you in the examples folder.

     

  2. This will not be the most robust pathfinding neural network and it’s not meant to be. This is not Google Maps and is not capable of navigating for Tesla’s cars. It will however provide you with the basic tools and knowledge to create your own pathfinding neural networks for games, research or anything else you can think of!

Since most of my posts tend to get a little long I am going to make this a multi part post as usual. I intend for this post to provide the code and cover the basics and in the next post in the series we will dig into the details.

Meet Pathfinder

pathfinder
Pathfinder has 25 input neurons (green), 3 hidden layers with 70 hidden neurons on each layer (red) and 25 output neurons (blue).

Pathfinder is an example of a neural network that is capable of plotting an 8 direction step path from a starting position in a 5×5 grid to an ending position in that grid.

8 Direction Stepping

8-direction-step-path
8 Direction Stepping means that movement can be expressed in not just up, down, left and right but also diagonal steps as well.

The Grid

5x5-grid
Pathfinder’s view of the world.

To keep the Pathfinder example simple it is not trained to deal with walls or non-traversable terrain however it would be very easy to add that by adding additional training, which I encourage you to do after following this tutorial!

Don’t worry, yes I will offer some advice on what you might do to improve upon it.

πŸ˜‰

Pathfinding

Pathfinding, is the act of finding a path. A path can be defined as a collective series of steps you would take to travel between two or more points.

Just for now we will keep things simple so we will define our map in strict binary terms: 1 or 0.

If you are wondering why we are excluding -1, Great question! We’re going to ignore it for now but we will use it later.

If you are now wondering why we don’t use floating point numbers to create a more dynamic grid full of gradient step paths that allow you to pick the best path provided rather than relying on Pathfinder to give you a single path… well aren’t you just the smarty pants, this is a tutorial and i’m trying to keep it simple! πŸ˜›

We will use 0 to represent “open” or “traversable” spaces.

We will use 1 to denote “steps” in our path as well as the “start” and “end” positions.

Example input

pathfinder-example-1
Traversable spaces with a start and stop location.

It’s important to note that because both start and stop are 1, either space can be interpreted as the start and stop positions and we are saying in this case that start is the bottom left (green) cell and stop is the top right cell (red). This neural network is only concerned with finding a path that connects these two points. If you were to use a pathfinder neural network that worked like this you would have to keep track of the start and stop positions outside of the neural network in X & Y variables in your code somewhere.

In terms of 2D vector space (x,y), where x is the row and y is the column, the position of the start can be interpreted as (4, 0). The position of the end can be interpreted as (0, 4).

Based on these start and stop positions we want pathfinder to return the grid with the equivalent step path of these vectors:

(4,0), (3,1), (2,2), (1,3), (0, 4)

Example Output

pathfinder-example-2

 

5x5-vectorgrid-1

So now that we have looked at what we want Pathfinder to do, lets look at how we make it happen.

It’s actually really easy!

We prepare a grid for evaluation by the neural network simply by rearranging the rows into a single line.

Example:

colorgrid

colorline

 

Once we have rearranged the data as illustrated we are ready to pass it to the neural network for processing.

As you can see in the Pathfinder Neural Network illustration above, Pathfinder has 25 input neurons and our rearranged grid has 25 values, a perfect match!

The Code

So now we can start looking at code, we will cover more detail in my next Pathfinder post however you can use this code to get started.

Remember you will need to setup a test environment with the FANN library. I have a tutorial on that here: Getting started with Neural Networks

pathfinder.data

134 25 25
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0

pathfinder_train.php

<?php 
$num_input = 25; 
$num_output = 25; 
$num_layers = 3; 
$num_neurons_hidden = 70; 
$desired_error = 0.001; 
$max_epochs = 5000000; 
$epochs_between_reports = 1000; 
$pathfinder_ann = fann_create_standard($num_layers, $num_input, $num_neurons_hidden, $num_output); 

if ($pathfinder_ann) { 
    fann_set_activation_function_hidden($pathfinder_ann, FANN_SIGMOID_SYMMETRIC); 
    fann_set_activation_function_output($pathfinder_ann, FANN_SIGMOID_SYMMETRIC); 

    $filename = dirname(__FILE__) . "/pathfinder.data"; 
    if (fann_train_on_file($pathfinder_ann, $filename, $max_epochs, $epochs_between_reports, $desired_error)) 
        fann_save($pathfinder_ann, dirname(__FILE__) . "/pathfinder_float.net"); fann_destroy($pathfinder_ann); 
    
    echo "<h1 class='green'>Training Complete!</h1><a href='pathfinder_test.php'>Test Pathfinder</a>"; 
}
?>

pathfinder_test.php

<html>
<head>
<style>
 .blue{color:blue;}
 .red{color:red;}
</style>
</head>
<body>
<?php
function Pathfinder($ann, $array) {
     $calc_out = fann_run($ann, $array);
     echo "<h1 class='blue'>Testing Pathfinder:</h1>";
     // Display Input Map
     for ($i = 0; $i <= 24; $i++){
         if(abs(round($array[$i]) == 1)) { 
             echo "<span class='red'>" . abs(round($array[$i])) . "</span>"; 
         }else {
            echo abs(round($array[$i]));
         }
         if($i > 0 && ($i % 5) - 4 == 0){
             echo "<br>" . PHP_EOL;
         }
    }
    echo "<h1 class='blue'>Results:</h1>";
    // Display Output Map
    for ($i = 0; $i <= 24; $i++){
       if(abs(round($calc_out[$i]) == 1)) { 
           echo "<span class='red'>" . abs(round($calc_out[$i])) . "</span>";
       }else {
           echo abs(round($calc_out[$i]));
       }
       if($i > 0 && ($i % 5) - 4 == 0){
         echo "<br>" . PHP_EOL;
       }
    }
}
$train_file = (dirname(__FILE__) . "/pathfinder_float.net");
if (!is_file($train_file)) {
     die('<span class="red">The file pathfinder_float.net has not been created! Please run <a href="pathfinder_train.php">pathfinder_train.php</a> to generate it</span>' . PHP_EOL);
}
$pathfinder_ann = fann_create_from_file($train_file);
if ($pathfinder_ann) {
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
   Pathfinder($pathfinder_ann, array(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0));
   Pathfinder($pathfinder_ann, array(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
   Pathfinder($pathfinder_ann, array(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0));
   Pathfinder($pathfinder_ann, array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0));
   fann_destroy($pathfinder_ann);
} else {
     die('<span class="red">Unable to open Pathfinder.</span>' . PHP_EOL);
}
?>
</body>
</html>

If you run this code you will have a working pathfinding neural network under your control! πŸ™‚

First run pathfinder_train.php then run pathfinder_test.php

In my next post in this series we will breakdown why this works and cover some ways we can make it even better!

As always, thanks for reading! If this post helps you or you found it enjoyable or just have some thoughts about all of this, please leave a comment below.

~Joy