¿Cómo construir un juego de tres en raya en Android?

En este artículo, construiremos un proyecto de juego Tic Tac Toe usando Java y XML en Android. El juego Tic Tac Toe se basa en un juego de dos jugadores. Cada jugador elige entre X y O. El jugador juega un movimiento a la vez simultáneamente. En un movimiento, un jugador puede elegir cualquier posición de una cuadrícula de 3×3. El objetivo aquí es obtener tres X u O consecutivas en dirección horizontal, vertical o diagonal. Habrá una sola actividad en esta aplicación. Esta actividad mostrará una cuadrícula de 3×3. El estado del juego se mostrará en la parte inferior. A continuación se proporciona un GIF de muestra para tener una idea de lo que vamos a hacer en este artículo. 

Build a Tic Tac Toe Game in Android Sample GIF

Implementación paso a paso

Paso 1: crear un nuevo proyecto

Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Java como lenguaje de programación.

Paso 2: antes de ir a la sección de codificación, primero debe hacer una tarea previa

Agregar imágenes: todas las imágenes se enumeran a continuación. Guárdelos en su carpeta dibujable en recursos. Ve a la aplicación > res > dibujable y pega los siguientes archivos:

Cambie el estilo a NoActionBar en el archivo themes.xml: 

<nombre de estilo=”AppTheme” parent=”Theme.AppCompat.NoActionBar”>

Paso 3: trabajar con el archivo activity_main.xml

Los códigos XML se utilizan para construir la estructura de la actividad, así como su parte de estilo. Contiene un TextView en la parte superior de la actividad para mostrar el título. Luego contiene un ImageView de la cuadrícula y en cada cuadro, hay un ImageView. En la parte inferior de la actividad, hay un TextView para mostrar el estado del juego. A continuación se muestra el código para el archivo activity_main.xml .

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    tools:context=".MainActivity">
  
    <!--title text-->
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="23dp"
        android:text="GFG Tic Tac Toe"
        android:textSize="45sp"
        android:textStyle="bold"
        app:fontFamily="cursive"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <!--image of the grid-->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:contentDescription="Start"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        app:srcCompat="@drawable/grid" />
  
    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="0dp"
        android:layout_height="420dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/imageView">
  
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
  
            <!--images of the grid boxes-->
            <ImageView
                android:id="@+id/imageView0"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="0" />
  
            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="1" />
  
            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="2" />
        </LinearLayout>
  
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
  
            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="3" />
  
            <ImageView
                android:id="@+id/imageView4"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="4" />
  
            <ImageView
                android:id="@+id/imageView5"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="5" />
        </LinearLayout>
  
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">
  
            <ImageView
                android:id="@+id/imageView6"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="6" />
  
            <ImageView
                android:id="@+id/imageView7"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="7" />
  
            <ImageView
                android:id="@+id/imageView8"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:onClick="playerTap"
                android:padding="20sp"
                android:tag="8" />
        </LinearLayout>
  
    </LinearLayout>
  
    <!--game status text display-->
    <TextView
        android:id="@+id/status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="15sp"
        android:text="Status"
        android:textSize="28sp"
        android:textStyle="italic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
  
</androidx.constraintlayout.widget.ConstraintLayout>

Paso 4: trabajar con el archivo MainActivity.java

Crearemos una array bidimensional que almacenará todas las posiciones ganadoras. Crearemos una función que se ejecutará cuando se haga clic en un cuadro dentro de la cuadrícula. Dentro de esta función, primero comprobaremos si la casilla seleccionada está vacía o no. Después de eso, configuraremos la imagen de X si el último movimiento fue de O o configuraremos la imagen de O si el último movimiento fue de X. Luego verificaremos si el movimiento ha alcanzado la posición de movimiento y luego reiniciaremos el juego. . MainActivity.java

Java

import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
  
import androidx.appcompat.app.AppCompatActivity;
  
public class MainActivity extends AppCompatActivity {
    boolean gameActive = true;
      
    // Player representation
    // 0 - X
    // 1 - O
    int activePlayer = 0;
    int[] gameState = {2, 2, 2, 2, 2, 2, 2, 2, 2};
      
    // State meanings:
    //    0 - X
    //    1 - O
    //    2 - Null
    // put all win positions in a 2D array
    int[][] winPositions = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
            {0, 3, 6}, {1, 4, 7}, {2, 5, 8},
            {0, 4, 8}, {2, 4, 6}};
    public static int counter = 0;
  
    // this function will be called every time a 
    // players tap in an empty box of the grid
    public void playerTap(View view) {
        ImageView img = (ImageView) view;
        int tappedImage = Integer.parseInt(img.getTag().toString());
          
        // game reset function will be called 
        // if someone wins or the boxes are full
        if (!gameActive) {
            gameReset(view);
        }
          
        // if the tapped image is empty
        if (gameState[tappedImage] == 2) {
            // increase the counter 
            // after every tap
            counter++;
              
            // check if its the last box
            if (counter == 9) {
                // reset the game
                gameActive = false;
            }
              
            // mark this position
            gameState[tappedImage] = activePlayer;
              
            // this will give a motion 
            // effect to the image
            img.setTranslationY(-1000f);
              
            // change the active player 
            // from 0 to 1 or 1 to 0
            if (activePlayer == 0) {
                // set the image of x
                img.setImageResource(R.drawable.x);
                activePlayer = 1;
                TextView status = findViewById(R.id.status);
                  
                // change the status
                status.setText("O's Turn - Tap to play");
            } else {
                // set the image of o
                img.setImageResource(R.drawable.o);
                activePlayer = 0;
                TextView status = findViewById(R.id.status);
                  
                // change the status
                status.setText("X's Turn - Tap to play");
            }
            img.animate().translationYBy(1000f).setDuration(300);
        }
        int flag = 0;
        // Check if any player has won
        for (int[] winPosition : winPositions) {
            if (gameState[winPosition[0]] == gameState[winPosition[1]] &&
                    gameState[winPosition[1]] == gameState[winPosition[2]] &&
                    gameState[winPosition[0]] != 2) {
                flag = 1;
                  
                // Somebody has won! - Find out who!
                String winnerStr;
                  
                // game reset function be called
                gameActive = false;
                if (gameState[winPosition[0]] == 0) {
                    winnerStr = "X has won";
                } else {
                    winnerStr = "O has won";
                }
                // Update the status bar for winner announcement
                TextView status = findViewById(R.id.status);
                status.setText(winnerStr);
            }
        }
        // set the status if the match draw
        if (counter == 9 && flag == 0) {
            TextView status = findViewById(R.id.status);
            status.setText("Match Draw");
        }
    }
  
    // reset the game
    public void gameReset(View view) {
        gameActive = true;
        activePlayer = 0;
        for (int i = 0; i < gameState.length; i++) {
            gameState[i] = 2;
        }
        // remove all the images from the boxes inside the grid
        ((ImageView) findViewById(R.id.imageView0)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView1)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView2)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView3)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView4)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView5)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView6)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView7)).setImageResource(0);
        ((ImageView) findViewById(R.id.imageView8)).setImageResource(0);
  
        TextView status = findViewById(R.id.status);
        status.setText("X's Turn - Tap to play");
    }
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Producción:

Publicación traducida automáticamente

Artículo escrito por namanjha10 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *