Wire the game screen to the model


Replace the MainActivity layout and connect it to TicTacToeModel

Replace activity_main.xml with the 3x3 grid

Replace the file content in app/src/main/res/layout/activity_main.xml with the grid below. Each button uses a tag in the form row,col and calls onCellClick.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:columnCount="3"
        android:rowCount="3">

        <Button
            android:id="@+id/button00"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="0,0"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button01"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="0,1"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button02"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="0,2"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button10"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="1,0"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button11"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="1,1"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button12"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="1,2"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button20"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="2,0"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button21"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="2,1"
            android:onClick="onCellClick"
            android:textSize="24sp" />

        <Button
            android:id="@+id/button22"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:tag="2,2"
            android:onClick="onCellClick"
            android:textSize="24sp" />

    </GridLayout>

</LinearLayout>

Update MainActivity.java to use the model

In app/src/main/java/com/example/tictacmenu/activities/MainActivity.java, remove the Edge-to-Edge setup, create the model, and handle cell clicks.

What this change is trying to achieve

Right now the game screen is just a layout. We want it to become a playable Tic-Tac-Toe screen that delegates all game rules to the external model. That means:

  • The Activity owns a TicTacToeModel instance.
  • Every button click becomes a move request to the model.
  • After each move, the UI updates to show the current player and resets the board if the game ends.

New events and how they are wired

onCellClick(View view)

  • This method is called directly by the XML. Each grid <Button> has android:onClick="onCellClick", so Android calls this method when the user taps that button.
  • The method reads the tag (like "0,1") to know which row/col the player selected.
  • It asks the model if the move is legal, then writes the current player symbol into the clicked button.
  • If the model reports a win or tie, it shows a Toast and resets the game state.

resetBoard()

  • This helper clears the UI after a win/tie.
  • It loops over the 9 button ids and resets their text to an empty string.

The wiring is purely XML-driven: the android:onClick attribute in activity_main.xml is what connects each button to onCellClick.

 import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
 
-import androidx.activity.EdgeToEdge;
 import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.graphics.Insets;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.WindowInsetsCompat;
 
 import com.example.tictacmenu.R;
+import com.example.tictacmenu.models.TicTacToeModel;
 
 public class MainActivity extends AppCompatActivity {
+    private TicTacToeModel model;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        EdgeToEdge.enable(this);
         setContentView(R.layout.activity_main);
-        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
-            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
-            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
-            return insets;
-        });
+        model = new TicTacToeModel();
+    }
+
+    public void onCellClick(View view) {
+        Button button = (Button) view;
+        String tag = button.getTag().toString();
+        String[] position = tag.split(",");
+        int row = Integer.parseInt(position[0]);
+        int col = Integer.parseInt(position[1]);
+
+        if (model.isLegal(row, col)) {
+            model.makeMove(row, col);
+            button.setText(model.getCurrentPlayer());
+
+            if (model.checkWin()) {
+                model.changePlayer();
+                Toast.makeText(this, "Player " + model.getCurrentPlayer() + " wins!", Toast.LENGTH_SHORT).show();
+                model.resetGame();
+                resetBoard();
+            } else if (model.isTie()) {
+                Toast.makeText(this, "It's a tie!", Toast.LENGTH_SHORT).show();
+                model.resetGame();
+                resetBoard();
+            } else {
+                model.changePlayer();
+            }
+        }
+    }
+
+    private void resetBoard() {
+        int[] buttonIds = {
+                R.id.button00, R.id.button01, R.id.button02,
+                R.id.button10, R.id.button11, R.id.button12,
+                R.id.button20, R.id.button21, R.id.button22
+        };
+
+        for (int id : buttonIds) {
+            Button button = findViewById(id);
+            button.setText("");
+        }
     }
 }

At the end of this step: the game screen uses the external model and the 3x3 grid is interactive. Commit if you are tracking steps.