Sunday, November 4, 2012

Android: Rock, Paper, Scissors

I'm giving my first baby steps in the Android development world. In this simple application I exemplify the use of:

  • Buttons
  • Click events
  • Image Views
  • Alert dialogs
The application is a simple game of "Rock, Paper, Scissors". User clicks on an image button according to the selection, and immediately the Android makes a random selection. According to the universal very well known rules of this game, an alert dialog is shown with the game result.

So here's the basic layout of the game. The two interrogation images are for displaying the two selections. The three images below are for the user to select an option.



















This is the layout XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:padding="@dimen/padding_medium"
        android:text="Rock, Paper, Scissors!"
        tools:context=".RockPaperScissors" />

    <Button
        android:id="@+id/buttonRock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="147dp"
        android:layout_marginRight="20dp"
        android:layout_toLeftOf="@+id/textView1"
        android:background="@drawable/rock_small" />

    <Button
        android:id="@+id/buttonPaper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonRock"
        android:layout_alignBottom="@+id/buttonRock"
        android:layout_centerHorizontal="true"
        android:background="@drawable/paper_small" />

    <Button
        android:id="@+id/buttonScissors"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonPaper"
        android:layout_alignBottom="@+id/buttonPaper"
        android:layout_marginLeft="23dp"
        android:layout_toRightOf="@+id/textView1"
        android:background="@drawable/scissors_small" />

    <ImageView
        android:id="@+id/imageViewAnswerUser"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="26dp"
        android:layout_toLeftOf="@+id/buttonPaper"
        android:src="@drawable/question" />

    <ImageView
        android:id="@+id/ImageViewAnswerAndroid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/buttonScissors"
        android:layout_alignTop="@+id/imageViewAnswerUser"
        android:src="@drawable/question" />

    <ImageButton
        android:id="@+id/imageButtonHome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/buttonPaper"
        android:layout_below="@+id/buttonPaper"
        android:layout_marginTop="38dp"
        android:src="@drawable/home" />

</RelativeLayout>

This is the code for the activity:
package com.example.mytoolbox;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;

public class RockPaperScissors extends Activity implements OnClickListener {
 
 public enum Option {
  ROCK, PAPER, SCISSORS
 }
 
 public enum Result {
  WIN, LOSS, DRAW  
 }
 
 private Option userSelection;
 private Result gameResult;
 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rock_paper_scissors);
        
        Button buttonRock = (Button) findViewById(R.id.buttonRock);
        Button buttonpaper = (Button) findViewById(R.id.buttonPaper);
        Button buttonScissors = (Button) findViewById(R.id.buttonScissors);
        ImageButton buttonHome = (ImageButton) findViewById(R.id.imageButtonHome);
        
        // Set click listening event for all buttons.
        buttonRock.setOnClickListener(this);
        buttonpaper.setOnClickListener(this);
        buttonScissors.setOnClickListener(this);
        buttonHome.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_rock_paper_scissors, menu);
        return true;
    }

 @Override
 public void onClick(View v) {
  
  ImageView imageView = (ImageView) findViewById(R.id.imageViewAnswerUser);
  boolean play = true;
  
  switch (v.getId()) {
   case R.id.buttonRock:
    userSelection = Option.ROCK;
    imageView.setImageResource(R.drawable.rock);
    break; 
   case R.id.buttonPaper:
    userSelection = Option.PAPER;
    imageView.setImageResource(R.drawable.paper);
    break;
   case R.id.buttonScissors:
    userSelection = Option.SCISSORS;
    imageView.setImageResource(R.drawable.scissors);
    break;
   case R.id.imageButtonHome:
    startActivity(new Intent(RockPaperScissors.this, ChooseActivity.class)); // To go home.
    play = false;
    break;
  }
  
  if(play) {
   play();
   showResults();
  }
 }

 private void showResults() {
  AlertDialog.Builder builder = new AlertDialog.Builder(RockPaperScissors.this);     
     builder.setCancelable(false);     
     builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {   
   @Override
   public void onClick(DialogInterface dialog, int which) {
    // Do nothing   
   }
  });
     
     // Sets the right message according to result.
     if(gameResult == Result.LOSS) {
      builder.setMessage("You Loose!");
     } else if(gameResult == Result.WIN) {
      builder.setMessage("You Win!");
     } else if(gameResult == Result.DRAW) {
      builder.setMessage("It's a draw!");
     } 
     
     AlertDialog alert = builder.create();
     alert.show();  
    } 

 private void play() {
  // Generates a random play.
  int rand =  ((int)(Math.random() * 10)) % 3;
  Option androidSelection = null;
  ImageView imageView = (ImageView) findViewById(R.id.ImageViewAnswerAndroid);
  
  // Sets the right image according to random selection.
  switch (rand) {
   case 0:
    androidSelection = Option.ROCK;
    imageView.setImageResource(R.drawable.rock);
    break;
   case 1:
    androidSelection = Option.PAPER;
    imageView.setImageResource(R.drawable.paper);
    break;
   case 2:
    androidSelection = Option.SCISSORS;
    imageView.setImageResource(R.drawable.scissors);
    break;
  }
  // Determine game result according to user selection and Android selection.
  if(androidSelection == userSelection) {
   gameResult = Result.DRAW;
  }
  else if(androidSelection == Option.ROCK && userSelection == Option.SCISSORS) {
   gameResult = Result.LOSS;
  }
  else if(androidSelection == Option.PAPER && userSelection == Option.ROCK) {
   gameResult = Result.LOSS;
  } 
  else if(androidSelection == Option.SCISSORS && userSelection == Option.PAPER) {
   gameResult = Result.LOSS;
  } else {
   gameResult = Result.WIN;
  }  
 }    
}

Running app:


4 comments:

  1. Hi Gabriel,

    I'm new to app development and wanted to test run your code above. Can you please help explain some of the errors I'm receiving?

    **This one in particular ImageView imageView = (ImageView) findViewById(R.id.ImageViewAnswerAndroid); **

    Does R.id.ImageViewAnswerAndroid need to be made as a new class? I'm receiving error as: "ImageViewAnswerAndroid cannot be resolved or is not a field type"

    Thank You!

    Jesse L.

    ReplyDelete
  2. Hello fellow developer,

    It's been a while since I did something Android related. But if something it's not compiling, it might be because I didn't include steps to create the GUI elements. "ImageViewAnswerAndroid" must be a GUI element you need to add.

    Maybe later on I can give it a better check.

    Good luck in your learning.

    ReplyDelete
  3. Hello, would you be able to provide a step by step tutuorial, im currently studying and finding android studio to be a bit challenging at times :)

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete