0

I have 9 buttons in an array and when I click a Button, the turn variable is set to the opposite boolean value to maintain turns.
When I run the app and click 3 X's or O's in all three rows it works and displays a toast message with the winner.
The problem is the columns: it only recognizes when I click 3 X's or O's in the 3rd column and displays a toast, but when I do the same with the first and second column, no toast/message is displayed.

The showWinner() method uses the determineWinner() method in order to display the message.

I need to find how to display the winner when they are in the 1st and 2nd columns.

my MainActivity:

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity implements         View.OnClickListener, AdapterView.OnItemSelectedListener  {
//declaring instance variables to keep track of the button views and user turns
private Button[] btns;
private boolean turn = false;
private Button[][] btnsWin;

//creating an array of buttons in order to easily reference them
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // create a toolbar and set it as the action bar
    Toolbar myToolBar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(myToolBar);

    btns = new Button[9];
    btnsWin = new Button[3][3];

    int id = R.id.button1;
    for(int i = 0; i < btns.length; i++)
    {
        btns[i] = (Button)findViewById(id);
        id++;
    }

    id = R.id.button1;
    for(int col = 0; col < btnsWin.length; col++)
        for(int row = 0; row < btnsWin[0].length; row++)
        {
            btnsWin[col][row] = (Button)findViewById(id);
            id++;
        }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    MenuItem spinnerItem = menu.findItem(R.id.color_spinner);

    Spinner spinner = (Spinner) MenuItemCompat.getActionView(spinnerItem);

    spinner.setOnItemSelectedListener(this);

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.colors_array, android.R.layout.simple_spinner_item);

    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    spinner.setAdapter(adapter);

    return true;
}

@Override
public void onClick(View v) {
    //get a handle on the textview in the xml
    switch (v.getId()) {
        case R.id.button1:
            //checks what turn the user is on and sets the text in the button to either an X or an O
            //depending on the turn. Then it sets the turn to the opposite boolean value.
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button2:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button3:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button4:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button5:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button6:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button7:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button8:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
        case R.id.button9:
            if (turn == false) {
                ((Button) v).setText("X");
                turn = !turn;
            } else {
                ((Button) v).setText("O");
                turn = !turn;
            }
            showWinner();
            v.setEnabled(false);
            break;
    }
}

public void showWinner()
{
    Toast toast1 = null;
    if(determineWinner().equals("X is the winner"))
    {
        toast1 = Toast.makeText(getApplicationContext(), "X is the winner", Toast.LENGTH_SHORT);
        toast1.show();
    }
    else if(determineWinner().equals("O is the winner"))
    {
        toast1 = Toast.makeText(getApplicationContext(), "O is the winner", Toast.LENGTH_SHORT);
        toast1.show();
    }
}

public void resetBtns()
{
    for(int i = 0; i < btns.length; i++)
    {
        btns[i].setEnabled(true);
        btns[i].setText(R.string.space);
    }
}

public void disableBtns()
{
    for(int j = 0; j < btns.length; j++)
    {
        btns[j].setText("");
        btns[j].setEnabled(false);
    }
}

public String determineWinner()
{
    String winner = " ";
    int xHorizontal = 0;
    int oHorizontal = 0;
    int xVertical = 0;
    int oVertical = 0;

    // checking for x's and o's vertically
    for(int x = 0; x < 3; x++)
    {
        if ((btns[x]).getText().equals("X") && (btns[x+3]).getText().equals("X") && (btns[x+6]).getText().equals("X")) {
            xVertical = 3;
            break;
        }
        else if ((btns[x]).getText().equals("O") && (btns[x+3]).getText().equals("O") && (btns[x+6]).getText().equals("O")) {
            oVertical = 3;
            break;
        }

    }

    // checking for x's and o's horizontally
    for(int i = 0; i < 9; i++)
    {
        if ((btns[i]).getText().equals("X") && (btns[i+1]).getText().equals("X") && (btns[i+2]).getText().equals("X")) {
            xHorizontal = 3;
            break;
        }
        else if ((btns[i]).getText().equals("O") && (btns[i+1]).getText().equals("O") && (btns[i+2]).getText().equals("O")) {
            oHorizontal = 3;
            break;
        }
        else
            i = i + 2;
    }



    if(oHorizontal == 3 || oVertical == 3)
    {
        winner = "O is the winner";
    }
    if(xHorizontal == 3 || xVertical == 3)
    {
        winner = "X is the winner";
    }



    return winner;
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    Toast toast;
    switch(item.getItemId())
    {
        case R.id.color_spinner:
            toast = Toast.makeText(getApplicationContext(), "Select which color for X's or O's", Toast.LENGTH_SHORT);
            toast.show();
            break;
        case R.id.action_favorite:
            resetBtns();
            toast = Toast.makeText(getApplicationContext(), "Buttons have been reset", Toast.LENGTH_LONG);
            toast.show();
            break;
    }
    return true;
}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int i, long id) {

    switch(i)
    {
        case 0:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("X"))
                    btns[j].setTextColor(Color.BLACK);
            break;
        case 1:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("O"))
                    btns[j].setTextColor(Color.BLACK);
            break;
        case 2:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("X"))
                    btns[j].setTextColor(Color.MAGENTA);
            break;
        case 3:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("O"))
                    btns[j].setTextColor(Color.MAGENTA);
            break;
        case 4:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("X"))
                    btns[j].setTextColor(Color.CYAN);
            break;
        case 5:
            for(int j = 0; j < btns.length; j++)
                if(btns[j].getText().equals("O"))
                    btns[j].setTextColor(Color.CYAN);
            break;
    }
}
}

my layout:

<?xml version="1.0" encoding="utf-8"?>
<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"
            tools:context="edu.ncc.tictactoe.MainActivity">

<android.support.v7.widget.Toolbar
    android:id="@+id/my_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<Button
    android:id="@+id/button1"
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:layout_toLeftOf="@+id/button2"
    android:layout_below="@id/my_toolbar"
    android:textSize="35sp"
    android:text="@string/space"
    android:onClick="onClick" />
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:id="@+id/button2"
    android:textSize="35sp"
    android:text=""
    android:layout_below="@+id/my_toolbar"
    android:layout_centerHorizontal="true"
    android:onClick="onClick"/>
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:layout_below="@id/my_toolbar"
    android:id="@+id/button3"
    android:textSize="35sp"
    android:text="@string/space"
    android:layout_toRightOf="@id/button2"
    android:onClick="onClick"/>
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:layout_below="@id/button1"
    android:layout_toLeftOf="@+id/button5"
    android:id="@+id/button4"
    android:textSize="35sp"
    android:text="@string/space"
    android:onClick="onClick"/>
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:id="@+id/button5"
    android:textSize="35sp"
    android:text="@string/space"
    android:onClick="onClick"
    android:layout_below="@+id/button2"
    android:layout_centerHorizontal="true" />
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:id="@+id/button6"
    android:textSize="35sp"
    android:text="@string/space"
    android:layout_below="@id/button3"
    android:layout_toRightOf="@id/button5"
    android:onClick="onClick"/>
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:layout_below="@id/button4"
    android:layout_toLeftOf="@+id/button8"
    android:id="@+id/button7"
    android:textSize="35sp"
    android:text="@string/space"
    android:onClick="onClick"/>
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:id="@+id/button8"
    android:textSize="35sp"
    android:text="@string/space"
    android:onClick="onClick"
    android:layout_below="@+id/button5"
    android:layout_centerHorizontal="true" />
<Button
    android:layout_width="116sp"
    android:layout_height="110sp"
    android:id="@+id/button9"
    android:textSize="35sp"
    android:text="@string/space"
    android:layout_toRightOf="@id/button8"
    android:layout_below="@id/button6"
    android:onClick="onClick"/>
</RelativeLayout>
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Michael Cera
  • 59
  • 1
  • 1
  • 4
  • `id++;`... What are you thinking this does? Your `R.id` values are likely not consecutive – OneCricketeer Oct 08 '16 at 05:13
  • the way you are initializing buttons works for you? i don't know it will work in every case or not because it is generated numbers and may have any value, you can do it like this too. `(Button) findViewById(getResources().getIdentifier("button" + (i+1), "id", getPackageName()));` – Prashant Oct 08 '16 at 05:14

1 Answers1

0

You need to access your views differently. id++ cannot be guaranteed to go from button1 to button2.

So, try something like this

btns = new Button[9];
btnsWin = new Button[3][3];

for(int i = 0; i < btns.length; i++)
{
    int resID = getResources().getIdentifier("button"+(i+1), "id", getPackageName());
    Button b = (Button) findViewById(resId);
    btns[i] = b;

    // I think this math is right...
    btnsWin[i / 3][i % 3] = b;
}

For more information see Android, getting resource ID from string?

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245