简体   繁体   English

二次点击仅Android按钮的启动方法

[英]Android button only initiating method on second click

I have a tic tac toe board made of buttons. 我有一个由按钮制成的井字游戏板。 Each button is linked to the method that initiated the logic. 每个按钮都链接到启动逻辑的方法。 The problem I'm having is that when the human player (noughts) plays their turn, the logic is skipping that turn, running the AIs turn and then only going back to the human player, who this time around is working as expected. 我遇到的问题是,当人类玩家(noughts)下他们的回合时,逻辑是跳过该回合,运行AI转向,然后只回到人类玩家,这一次正在按预期工作。

On the click, the button is question should have setText method called and marked with either a 'O' for the human player, or 'X' for the AI. 在单击时,按钮是否有问题,应该调用setText方法并将其标记为人类玩家的“ O”或AI的“ X”。 Following this the button is set to inactive and the array that tracks the board changes. 此后,该按钮将设置为非活动状态,并且跟踪板的阵列也会更改。

I am printing to the logs and from what I can see, the human users clicks are what are triggering the AIs moved, rather than this being done automatically. 我正在打印日志,从我所看到的来看,人类用户的点击是触发移动AI的原因,而不是自动完成的。 But I can't tell why this is happening. 但是我不能说为什么会这样。 I assume there is a flaw in my logic but I can't pick out what the issue is. 我认为我的逻辑存在缺陷,但是我无法找出问题所在。 EDIT: It works fine for the first human click, it is the ones after that that are the problem. 编辑:第一次人为点击就可以正常工作,这就是问题所在。

Code: 码:

package com.example.richardcurteis.connect3;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import java.util.Random;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    boolean noughtsTurn;
    ArrayList board;
    Players player;
    int aiPickedButton;
    int buttonPressed;
    int targetIndex;

    public void receiveClick(View view) {
        String takeButton = String.valueOf(view.getTag());
        buttonPressed = Integer.parseInt(takeButton);
        playNow(view);
        //checkForWin; Check winning conditions. Not yet implemented
    }

    public void playNow(View view) {
        if (noughtsTurn) {
            System.out.println("Player picked: " + buttonPressed);
            playerClick(view);
        } else {
            if (aiValidPick()) {
                playerClick(view);
            } else {
                playNow(view);
            }
        }
    }

    public void setTurn(boolean trueOrFalse) {
        if (trueOrFalse) {
            noughtsTurn = false;
        } else {
            noughtsTurn = true;
        }
    }

    public void playerClick(View view) {
        Button B;
        int boardSetIndex;
        int boardSetValue;

        if (view instanceof Button) {
            B = (Button) view;
            if ( noughtsTurn ) {
                B.setText(player.noughtsPlayer());
            } else {
                B = aiPlayerPick();
                System.out.println("AI picked: " + targetIndex);
                B.setText(player.crossesPlayer());
            }
            board.set(boardSetIndex(), boardSetValue());
            System.out.println("Board: " + board);
            B.setEnabled(false);
            setTurn(noughtsTurn);
        }
    }

    public int boardSetIndex() {
       int index;
        if (noughtsTurn) {
            index = buttonPressed;
        } else {
            index = targetIndex;
        }
        return  index;
    }

    public int boardSetValue() {
        int value;
        if (noughtsTurn) {
            value = player.humanTurnValue();
        } else {
            value = player.aiTurnValue();
        }
        return  value;
    }

    public Integer randomButtonPick() {
        Random randomNumber = new Random();
        int randomInt = randomNumber.nextInt(board.size());
        return randomInt;
    }

    public boolean aiValidPick() {
        aiPickedButton = randomButtonPick();
        if (board.get(aiPickedButton).equals(player.boardArrayDefaultValue())
                && !board.get(aiPickedButton).equals(player.humanTurnValue())
                && !board.get(aiPickedButton).equals(player.aiTurnValue())){
            return true;
        } else {
            return false;
        }
    }

    public Button aiPlayerPick() {
        Button btn = null;
        TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
        for (int rowIndex = 0; rowIndex < tableLayout.getChildCount(); rowIndex++) {
            View tableLayoutChild = tableLayout.getChildAt(rowIndex);
            if (tableLayoutChild instanceof TableRow) {
                for (int i = 0; i < ((ViewGroup) tableLayoutChild).getChildCount(); i++) {
                    View view = ((ViewGroup) tableLayoutChild).getChildAt(i);
                    String targetButton = String.valueOf(aiPickedButton);
                    if (view instanceof Button && view.getTag().equals(targetButton) ) {
                        targetIndex = Integer.parseInt(targetButton);
                        View btn_v = view.findViewWithTag(targetButton);
                        btn = (Button) btn_v;
                        break;
                    }
                }
            }
        }
        return btn;
    }

    public class Players {
        public String noughtsPlayer() { return "O"; }
        public String crossesPlayer() { return "X"; }
        //public String blankButton() { return ""; }

        public int humanTurnValue() { return 0;}
        public int aiTurnValue() { return 1;}
        public int boardArrayDefaultValue() { return 2;}
    }

    public int getBoardSize() {
        int buttonCount = 0;
        TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
        for (int rowIndex = 0; rowIndex < tableLayout.getChildCount(); rowIndex++) {
            View tableLayoutChild = tableLayout.getChildAt(rowIndex);
            if (tableLayoutChild instanceof TableRow) {
                for (int i = 0; i < ((ViewGroup) tableLayoutChild).getChildCount(); i++) {
                    View view = ((ViewGroup) tableLayoutChild).getChildAt(i);
                    if (view instanceof Button) {
                        buttonCount++;
                    }
                }
            }
        }
        return buttonCount;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        noughtsTurn = true;
        player = new Players();
        board = new ArrayList();
        int boardSize = getBoardSize();
        for (int boardIndex = 0; boardIndex < boardSize; boardIndex++) {
            board.add(player.boardArrayDefaultValue());
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

XML XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.richardcurteis.connect3.MainActivity"
    tools:showIn="@layout/activity_main"
    android:background="#070000">

    <TableLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="false"
        android:layout_alignParentEnd="false"
        android:layout_alignParentStart="false"
        android:layout_centerInParent="true"
        android:id="@+id/tableLayout"
        android:background="#000000">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton1"
                android:layout_column="4"
                android:onClick="receiveClick"
                android:tag="0" />
                android:nestedScrollingEnabled="false" />

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton2"
                android:layout_column="12"
                android:onClick="receiveClick"
                android:tag="1" />

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton3"
                android:layout_column="19"
                android:onClick="receiveClick"
                android:tag="2" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton4"
                android:layout_column="4"
                android:onClick="receiveClick"
                android:tag="3"/>

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton5"
                android:layout_column="12"
                android:onClick="receiveClick"
                android:tag="4"/>

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton6"
                android:layout_column="19"
                android:onClick="receiveClick"
                android:tag="5"/>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent"></TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton7"
                android:layout_column="4"
                android:onClick="receiveClick"
                android:tag="6"/>

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton8"
                android:layout_column="12"
                android:onClick="receiveClick"
                android:tag="7"/>

            <Button
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:id="@+id/gridButton9"
                android:layout_column="19"
                android:onClick="receiveClick"
                android:tag="8" />
        </TableRow>
    </TableLayout>

    <Button

        android:layout_width="200dp"
        android:layout_height="120dp"
        android:text="New Game"
        android:id="@+id/newGameButton"
        android:layout_below="@+id/tableLayout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="61dp" />
</RelativeLayout>

The issue is not in your logic. 问题不属于您的逻辑。 The issue is how it is implemented. 问题是如何实施。

You currently have a step-by-step logic system in place where each step in the logic is triggered by the receiveClick(View) method. 当前,您已经有一个逐步的逻辑系统,其中的每个逻辑步骤都由receiveClick(View)方法触发。 The problem is that there is no automatic triggering of the AI turn. 问题在于没有自动触发AI转向。

  1. noughtsTurn = true noughtsTurn =真
  2. receiveClick(View) works properly with the players turn. receiveClick(View)可以在玩家回合时正常工作。
  3. The turn logic completes in playerClick(View) with the value of noughtsTurn being inverted. 转牌逻辑在playerClick(View)中完成,其中noughtsTurn的值被反转。
  4. The problem is nothing triggers the AI turn and the next time you click a button it calls receiveClick(View) but with a noughtsTurn value of false. 问题是什么都不会触发AI旋转,并且下次单击按钮时它将调用receiveClick(View),但是noughtsTurn值为false。
  5. So this simulates an AI turn even though the player just clicked. 因此,即使玩家刚刚单击,它也会模拟一个AI回合。

You need to add some sort of logic to the end of playerClick(View) so that if the player just took their turn it reruns the logic for the AI turn. 您需要在playerClick(View)的末尾添加某种逻辑,以便如果玩家刚刚转身,它将重新运行AI转身的逻辑。

Example: 例:

public void playerClick(View view) {
    Button B;
    int boardSetIndex;
    int boardSetValue;

    if (view instanceof Button) {
        B = (Button) view;
        if ( noughtsTurn ) {
            B.setText(player.noughtsPlayer());
        } else {
            B = aiPlayerPick();
            System.out.println("AI picked: " + targetIndex);
            B.setText(player.crossesPlayer());
        }
        board.set(boardSetIndex(), boardSetValue());
        System.out.println("Board: " + board);
        B.setEnabled(false);
        //
        if(setTurn(noughtsTurn) == false){
            playNow(findViewByTag(randomButtonPick()))
        }
        //
    }
}

In the above example there are some critical things missing like checking that the randomButtonPick() is not already occupied and the fact that setTurn(boolean) returns void and not a boolean. 在上面的示例中,缺少一些关键的东西,例如,检查randomButtonPick()是否尚未被占用,以及setTurn(boolean)返回void而不是布尔值的事实。 You just need some way of checking if the player just took a turn and, if so, have the AI take a turn. 您只需要某种方式来检查玩家是否刚刚转过弯,如果是,就让AI转弯。

Ok, so here is the final solution I came to for this issue. 好的,这是我解决此问题的最终解决方案。 I kept the same logic but separated the human and AI turns into separate methods with the AI still basing it's turn on the noughtsTurn method. 我保持相同的逻辑,但是将人工和AI分离为单独的方法,而AI仍然基于noughtsTurn方法。

Code: 码:

public void receiveClick(View view) {
        String takeButton = String.valueOf(view.getTag());
        buttonPressed = Integer.parseInt(takeButton);
        humanPlayerTurn(view);
        aiPlayerTurn(view);
    }

    public void humanPlayerTurn(View view) {
        if (noughtsTurn) {
            System.out.println("Player picked: " + buttonPressed);
            playerClick(view);
        }
    }

    public void aiPlayerTurn(View view) {
        if (aiValidPick()) {
            playerClick(view);
        } else {
            aiPlayerTurn(view);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM