[英]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转向。
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.