In the previous tutorial, we have implement the game part. We now need to add our neural network to the game to automate player jumps. Make sure to download the complete project files.
[wpi_designer_button text=’Download’ link=’https://github.com/arjunsk/phaser_ai_game’ style_id=’48’ icon=’github’ target=’_blank’]
&
[wpi_designer_button text=’Presentation slides’ link=’https://www.slideshare.net/ArjunSK15/jumper-ai-game’ style_id=’48’ icon=’show’ target=’_blank’]
Before we start, we need to get introduced to some ANN(Artificial neural network) terms!
Terminology
Neural Networks :
- Inspired from human brain design.
- Interconnected processing elements (neurons) working in unison to solve specific problems.
Supervised Learning:
- We teach the neural network with input and output patterns, so that next time something similar comes, it know what to do.
Perceptron:
- Perceptron is an algorithm for supervised learning.
- It is a type of linear classifier, i.e. a classification algorithm that makes its predictions based input and weight of each edge in the neuron.
Let’s see some code
ANN variables :
//NN var nn_network; var nn_trainer; var nn_output; var trainingData=[]; var auto_mode = false; var training_complete=false;
Initializing ANN :
// Neural Network nn_network = new synaptic.Architect.Perceptron(2, 6, 6, 2); /* First param => number of neurons in input layer Second param=> number of neurons in hidden layer1 Third param => number of neurons in hidden layer2 .. .. .. Last param => number of neurons in output layer Basically we have two inputs ie displacement and speed of the ball we also have two output denoting the state of the player, ON AIR or ON LAND */ nn_trainer = new synaptic.Trainer(nn_network); // Create trainer
Training ANN :
function train_nn(){ nn_trainer.train(trainingData, { rate: 0.0003, // learning rate iterations: 10000, // one pass = one forward pass + one backward pass shuffle: true // the training set is shuffled after every iteration, }); }
Activating ANN and getting the respective output of custom input
function get_op_from_trainedData(input_param){ nn_output = nn_network.activate(input_param); // send input to network and return output array var on_air=Math.round( nn_output[0]*100 ); // we get ouput as fuzzy values ie 0.7 etc var on_floor=Math.round( nn_output[1]*100 ); console.log("Forecast ","ON AIR %: "+ on_air + " ON FLOOR %: " + on_floor ); // we use Maximum-Membership priciple to defuzzify the output. ie we take the maximum to be the output state return nn_output[0]>=nn_output[1]; }
Calling train_nn()
// We call it when user clicks on Auto mode in the popup menu }else if (mouse_x >=menu_x1 && mouse_x <=menu_x2 && mouse_y >=menu_y1+90 && mouse_y <=menu_y2) { if(!training_complete) { console.log("","Training using Data set of "+ trainingData.length +" elements" ); train_nn(); training_complete=true; // setting flag after training completion } auto_mode = true; }
getting training dataset :
In order to get the training dataset(during manual mode) for this supervised learning network, we are getting displacement and speed value at each frame in the update().
bullet_displacement = Math.floor( player.position.x - bullet.position.x ); // Collecting Training Set if( auto_mode==false && bullet.position.x > 0 ){ trainingData.push({ 'input' : [bullet_displacement , bullet_speed], 'output': [stay_on_air , stay_on_floor ] // jump now , stay on floor }); console.log("BULLET DISPLACEMENT, BULLET SPEED, Stay on Air?, Stay on Floor?: ", bullet_displacement + " " +bullet_speed + " "+ stay_on_air+" "+ stay_on_floor ); }
we get the ball’s speed from the fire function
function fire(){ bullet_speed = -1 * getRandomSpeed(300,800); bullet.body.velocity.y = 0 ; bullet.body.velocity.x = bullet_speed ; bullet_fired=true; } function getRandomSpeed(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
Making the automated jump
It is also done in the update()
// Auto Jump if( auto_mode==true && bullet.position.x>0 && player.body.onFloor() ){ if( get_op_from_trainedData( [bullet_displacement , bullet_speed] ) ){ jump(); } }