How to make a Machine Learning Android Game from scratch

Written by pradyumandixit | Published 2019/01/20
Tech Story Tags: machine-learning | artificial-intelligence | android | android-app-development | game-development

TLDRvia the TL;DR App

Let’s make an android machine learning game from scratch 🌟.

Are you fascinated by machine learning? Do you like Java or Android? Do you want to make a cool project using android and machine learning?

If yes, then you’re certainly at the right place. Here we will be making an android application which uses machine learning to defeat the user.

Yes, defeat!! That means as you play along, it will become more and more pro at the game and your techniques, so you better prepare to lose.

But even after losing, you’ll definitely be proud. Why, you ask?

Well, you made it learn, and you made it pro in the game. So, who’s the boss?

For starting purposes, let’s start with a simple game, with less possibilities. I think something like, Rock, Paper and Scissors will do just fine.

This post will help you understand how you can make a game with machine learning and android, so you can make an amazing project game of your own, after this!

Let’s dive into understanding how our app will progress, in a simple flow chart.

Android App → Gives options for Rock/Paper/Scissor → User chooses one of them → If first time, then a random choice by computer → Otherwise, computer analyses the user input, and uses statistics to choose the one with more probability to win → Game continues, computer becomes more pro.

So this is our app in a flow chart, which will give us direction, when we are stuck at what to do now.

Simple Developer Tip: Always make a simple flow chart before making an app, to guide your journey during it’s making.

Now let’s dive into some code.

Start a new project on Android Studio or IDE of your choice. Head toward the MainActivity.java file. We will start with the Java code, first.

Let’s first initialise some variables and flags. So add the following code for that in your MainActivity.

/*first two are for previous result second two are for recent result*results[0][x][0][x] 0 at index 0 or 2 is a win*results[1][x][1][x] 1 at index 0 or 2 is a tie*results[2][x][2][x] 2 at index 0 or 2 is a loss*results[x][0][x][0] 0 at index 1 or 3 is for rock*results[x][1][x][1] 1 at index 1 or 3 is for scissors*results[x][2][x][2] 2 at index 1 or 3 is for paper*/

private int[][][][][][] results6D = new int[3][3][3][3][3][3];private int[][][][] results4D = new int[3][3][3][3];private int[][] results2D = new int [3][3];

private int lastResult =- 1;private int lastCompMove =- 1;

private int secondResult =- 1;private int secondCompMove =- 1;

private int status = 0;

I have commented in the code for more understanding. We will be using last and recent choices by the user to train our Machine Learning model.

Now we should add the code that gives user the choice to choose from Rock, Paper and Scissor. Also the code which shows what the computer drew, and the result of the game.

The code like this would do for the above discussed aspect of our game, also this is the code inside the userMove(view) method of our code.

int userMoveInt;

Button b = (Button) v;String name = b.getText().toString();

switch (name) {case ("Rock"): {userMoveInt = 0;break;}case ("Paper"): {userMoveInt = 1;break;}default:userMoveInt = 2;}

int compMoveInt;String compMoveStr;int resultStatus;compMoveInt = nextCompMove();

if (compMoveInt == 0)compMoveStr = "rock";

else if (compMoveInt == 1)compMoveStr = "paper";

else if (compMoveInt == 2)compMoveStr = "scissors";

elsecompMoveStr = "nothing";

String text = "I drew "+compMoveStr+", ";resultStatus = checkResult(compMoveInt,userMoveInt);

if (resultStatus == 0)text+="You Win!";

else if (resultStatus == 1)text += "It's a Tie.";

else if (resultStatus == 2)text += "You Lose!";

TextView output = findViewById(R.id.output);output.setText(text);trainModel(resultStatus,compMoveInt);

float[] percentages = analyzeResults();int[] changes = changes(percentages);int rockChance = changes[0];int paperChance = changes[1];

text = "Rock: "+String.valueOf(rockChance)+"%";

((TextView) findViewById(R.id.rPer)).setText(text);text = "Paper: "+String.valueOf(paperChance)+"%";

((TextView) findViewById(R.id.pPer)).setText(text);text = "Scissors: "+String.valueOf(100-rockChance-paperChance)+"%";

((TextView) findViewById(R.id.sPer)).setText(text);

int top = Math.max(rockChance,Math.max(paperChance,100-rockChance-paperChance));text = "Confidence\n"+String.valueOf(Math.round(2*(top-50)))+"%";

((TextView) findViewById(R.id.confidence)).setText(text);

Also we are using integer 0 for rock, 1 for paper and 2 for scissors.

Now let’s write some code for the computer to choose and learn from the user. Also, this code is inside the method nextCompMove() of our code.

if (lastResult == -1) // that's default for the paperreturn 1;

int chanceOneHundred = (int)(Math.random()*99)+1;float[] percentages = analyzeResults();int[] changes = changes(percentages);int rockChance = changes[0];int paperChance = changes[1];int compMove;

if (chanceOneHundred < rockChance)compMove = 0;

else if (chanceOneHundred<rockChance+paperChance)compMove = 1;

elsecompMove = 2;

return compMove;

If you understand a bit of probability, then you know, choosing any one of rock, paper or scissors at random has probability 1/3 or ~33%.

So, we are putting the default chances for every choice, as 33%. The code to change the choices, for the method changes(percentage) looks something like this:

int totalPercentages = (int) (percentages[0]+percentages[1]+percentages[2]);int rockChance = 33;int paperChance = 33;

if (totalPercentages != 0) {rockChance= (int) (100*percentages[0]/totalPercentages);paperChance= (int) (100*percentages[1]/totalPercentages);}

return new int[]{rockChance, paperChance};

Now let’s help computer analyse the moves of the user, and choose something that has the most probability to win the game for the computer.

That will be our code for the method analyzeResults() :

float[] percentages=new float[3];if (lastResult == -1)return percentages;

    int\[\]\[\] relevantResults;  
    //noinspection ConstantConditions  
      
        if (lastResult!=-1) {  

        int\[\]\[\] resultsTo2D;  
        int\[\]\[\] results4DTo2D = results4D\[lastResult\]\[lastCompMove\];  
        if (secondResult!=-1) {  
            int\[\]\[\] results6DTo2D=results6D\[secondResult\]\[secondCompMove\]\[lastResult\]\[lastCompMove\];  
            resultsTo2D = _totalAmount_(results6DTo2D)<_totalAmount_(results4DTo2D)&&_totalAmount_(results6DTo2D)<9?results4DTo2D:results6DTo2D;  
        }  

        else  
            resultsTo2D = results4DTo2D;  

        relevantResults = _totalAmount_(resultsTo2D)<_totalAmount_(results2D)&&_totalAmount_(resultsTo2D)<1?results2D:resultsTo2D;  
    }  
    else  
        relevantResults = results2D;  
    for (int i=0;i<percentages.length;i++) {  

// percentages[i]=1+(relevantResults[2][i]*4+relevantResults[1][i]-relevantResults[0][1]*2);percentages[i]=1+(relevantResults[2][i]+relevantResults[0][i2?0:i+1])*4-(relevantResults[0][i]+relevantResults[2][i0?2:i-1])*4;if (percentages[i] < 0)percentages[i]=0;}return percentages;

Take some time to understand this code, which is almost self explanatory. If you understand this, you almost understand the whole code for the game.

Let’s also complete the trainModel(resultStatus, compMove) code, so we’re done with the machine learning crux part of the game.

if (lastResult != -1) {results4D[lastResult][lastCompMove][resultStatus][compMoveInt]++;

if (secondResult != -1)  
    results6D\[secondResult\]\[secondCompMove\]\[lastResult\]\[lastCompMove\]\[resultStatus\]\[compMoveInt\]++;  

secondResult=lastResult;  
secondCompMove=lastCompMove;  

}

results2D[resultStatus][compMoveInt]++;lastResult=resultStatus;lastCompMove=compMoveInt;

And you’re all done. You’ve made yourself a machine learning android game, which almost certainly wins against the user.

But, wait! Where’s the winning part? We certainly don’t want to leave the user in dark, about who won the game, now do we?

So, let’s write the code for checkResult(compMove, userMove) which tells the user, about the winning or losing of the game.

/*Status 0 is a win*Status 1 is a tie*Status 2 is a loss*/int resultStatus;if (compMoveInt == 0 && userMoveInt == 1 || compMoveInt == 1 && userMoveInt == 2 || compMoveInt == 2 && userMoveInt == 0) {resultStatus = 0;TextView wins= findViewById(R.id.wins);int winAmount=Integer.parseInt(wins.getText().toString());wins.setText(String.valueOf(winAmount+1));}else if (compMoveInt == userMoveInt) {resultStatus = 1;TextView ties = findViewById(R.id.ties);int tieAmount = Integer.parseInt(ties.getText().toString());ties.setText(String.valueOf(tieAmount+1));}else {resultStatus = 2;TextView losses = findViewById(R.id.losses);int lossAmount = Integer.parseInt(losses.getText().toString());losses.setText(String.valueOf(lossAmount+1));}

return resultStatus;

And yes, now you’ve coded yourself everything you need for your machine learning android game to work and defeat anyone.

The UI and some other fine tweaking in the code, can be found on my GitHub repository.

The full source code for the app.

You’re all done now, for sure.

What are you waiting for? Go show your friends how pathetically they can lose to your android game.

Go and Show Off !

Read my previous post about making a simple animated and clean website easily.


Published by HackerNoon on 2019/01/20