我正在为一个项目构建一个基本的tic tac toe应用程序,并且我正在尝试为玩家添加基本AI(只是一个随机数)。
它应该根据ArrayList
的长度选择一个随机数,其中每个值代表棋盘上的按钮或方块。
我们的想法是将整数值转换为字符串并用于选择带有匹配标记的按钮,使用getTag()
。
问题是,当我循环遍历布局中的按钮时,语句无法找到带有标记的按钮,并跳过它包含的必要逻辑,以便AI轮流播放。
然后,应该使用X
填充相关按钮,将其设置为无效并返回。
我添加了System.out.println("");
语句以帮助调试,我可以看到它正在按预期停止工作。
问题在于aiPlayerPick()
方法。
MainActivity.java
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;
public void receiveClick(View view) {
String takeButton = String.valueOf(view.getTag());
buttonPressed = Integer.parseInt(takeButton);
humanPlayerTurn(view);
aiPlayerTurn(view);
}
public void humanPlayerTurn(View view) {
playerClick(view);
noughtsTurn = false;
}
public void aiPlayerTurn(View view) {
aiPickedButton = randomButtonPick();
playerClick(view);
noughtsTurn = true;
}
public void playerClick(View view) {
Button B;
if (view instanceof Button) {
B = (Button) view;
if ( noughtsTurn ) {
B.setText(player.noughtsPlayer());
board.set(buttonPressed, 0);
B.setEnabled(false);
} else {
aiPlayerPick();
}
}
}
public Integer randomButtonPick() {
Random randomNumber = new Random();
int randomInt = randomNumber.nextInt(board.size());
System.out.println("Random Integer Picked for use as index by AI: " + randomInt);
return randomInt;
}
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);
// Change index back to string to find tag
String targetButton = (String) String.valueOf(aiPickedButton);
System.out.println("Progress 1 and targetButton class: "
+ targetButton.getClass() + " " + targetButton);
if (view instanceof Button && view.getTag() == targetButton) { // This appears to be where the logic breaks down
int targetIndex = Integer.parseInt(targetButton);
System.out.println("Progress 2");
View btn_v = view.findViewWithTag(targetButton);
btn = (Button) btn_v;
System.out.println("Progress 3");
btn.setText(player.crossesPlayer());
board.set(targetIndex, 1);
btn.setEnabled(false);
break;
} else {
i++;
}
}
}
}
return btn;
}
public class Players {
public String noughtsPlayer() { return "O"; }
public String crossesPlayer() { return "X"; }
public String blankButton() { return ""; }
}
@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;
board = new ArrayList();
int boardSize = getBoardSize();
for (int boardIndex = 0; boardIndex < boardSize; boardIndex++) {
board.add(2);
}
player = new Players();
}
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++;
}
}
}
}
System.out.println("Number of buttons: " + buttonCount);
return buttonCount;
}
@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);
}
}
content_main.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>
日志输出:
01-05 20:59:23.583 10380-10380/com.example.richardcurteis.connect3 I/art: Not late-enabling -Xcheck:jni (already on)
01-05 20:59:23.813 10380-10380/com.example.richardcurteis.connect3 W/System: ClassLoader referenced unknown path: /data/app/com.example.richardcurteis.connect3-2/lib/x86
01-05 20:59:24.224 10380-10380/com.example.richardcurteis.connect3 I/System.out: Number of buttons: 9
01-05 20:59:24.275 10380-10394/com.example.richardcurteis.connect3 D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
01-05 20:59:24.480 10380-10394/com.example.richardcurteis.connect3 I/OpenGLRenderer: Initialized EGL, version 1.4
01-05 20:59:24.543 10380-10394/com.example.richardcurteis.connect3 W/EGL_emulation: eglSurfaceAttrib not implemented
01-05 20:59:24.543 10380-10394/com.example.richardcurteis.connect3 W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xad79f5a0, error=EGL_SUCCESS
01-05 20:59:25.192 10380-10380/com.example.richardcurteis.connect3 I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread.
01-05 20:59:25.378 10380-10386/com.example.richardcurteis.connect3 W/art: Suspending all threads took: 49.644ms
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Random Integer Picked for use as index by AI: 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 20:59:51.722 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 6
01-05 21:00:00.751 10380-10380/com.example.richardcurteis.connect3 I/System.out: Random Integer Picked for use as index by AI: 5
01-05 21:00:00.751 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:00.752 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:00.752 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:00.752 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:00.752 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:00.752 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 5
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Random Integer Picked for use as index by AI: 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
01-05 21:00:05.129 10380-10380/com.example.richardcurteis.connect3 I/System.out: Progress 1 and targetButton class: class java.lang.String 0
答案 0 :(得分:0)
如评论中所述,而不是:
view.getTag() == targetButton
使用:
view.getTag().equals(targetButton)
的良好链接