There is the XML layout
I past the code in pastebin because it's too long
I'm Trying To build the tic tac toe game and It's work Perfectly but when I click the last button that it's will be in the row the The app Get crush. it's work great but I don't know why it's give me this error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ziadabouelfarah.tictactoy, PID: 6182
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.amin(ZygoteInit.java:767)
Caused by: java.lang.IllegalArgumentException: bound must be positive
at java.util.Random.nextInt(Random.java:388)
at com.agefinder.hell.MainActivity.autoPlay(MainActivity.kt:173)
at com.agefinder.hell.MainActivity.PlayGame(MainActivity.kt:54)
at com.agefinder.hell.MainActivity.buSelect(MainActivity.kt:37)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
And my code in Kotlin Is like the following:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main)
}
fun buSelect(view:View){
val buSelected= view as Button
var cellID=0
when(buSelected.id){
R.id.bt1-> cellID=1
R.id.bt2-> cellID=2
R.id.bt3-> cellID=3
R.id.bt4-> cellID=4
R.id.bt5-> cellID=5
R.id.bt6-> cellID=6
R.id.bt7-> cellID=7
R.id.bt8-> cellID=8
R.id.bt9-> cellID=9
}
// Toast.makeText(this,"ID:"+ cellID, Toast.LENGTH_LONG).show()
PlayGame(cellID,buSelected)
Thread.sleep(500)
}
var player1=ArrayList<Int>()
var player2=ArrayList<Int>()
var ActivePlayer=1
fun PlayGame(cellID:Int,buSelected:Button){
if(ActivePlayer==1){
buSelected.text="X"
buSelected.setBackgroundResource(R.color.pink)
player1.add(cellID)
ActivePlayer=2
//Thread.sleep(500)
autoPlay()
}else{
buSelected.text="O"
buSelected.setBackgroundResource(R.color.colorPrimaryDark)
player2.add(cellID)
ActivePlayer=1
}
buSelected.isEnabled=false
CheckWiner()
}
fun CheckWiner(){
var winer=-1
// row 1
if(player1.contains(1) && player1.contains(2) && player1.contains(3)){
winer=1
}
if(player2.contains(1) && player2.contains(2) && player2.contains(3)){
winer=2
}
// row 2
if(player1.contains(4) && player1.contains(5) && player1.contains(6)){
winer=1
}
if(player2.contains(4) && player2.contains(5) && player2.contains(6)){
winer=2
}
// row 3
if(player1.contains(7) && player1.contains(8) && player1.contains(9)){
winer=1
}
if(player2.contains(7) && player2.contains(8) && player2.contains(9)){
winer=2
}
// col 1
if(player1.contains(1) && player1.contains(4) && player1.contains(7)){
winer=1
}
if(player2.contains(1) && player2.contains(4) && player2.contains(7)){
winer=2
}
// col 2
if(player1.contains(2) && player1.contains(5) && player1.contains(8)){
winer=1
}
if(player2.contains(2) && player2.contains(5) && player2.contains(8)){
winer=2
}
// col 3
if(player1.contains(3) && player1.contains(6) && player1.contains(9)){
winer=1
}
if(player2.contains(3) && player2.contains(6) && player2.contains(9)){
winer=2
}
if(player1.contains(1) && player1.contains(5) && player1.contains(9)){
winer=1
}
if(player2.contains(1) && player2.contains(5) && player2.contains(9)){
winer=2
}
if(player1.contains(3) && player1.contains(5) && player1.contains(7)){
winer=1
}
if(player2.contains(3) && player2.contains(5) && player2.contains(7)){
winer=2
}
if( winer != -1){
if (winer==1){
Toast.makeText(this," Player 1 win the game", Toast.LENGTH_LONG).show()
}else{
Toast.makeText(this," Computer win the game", Toast.LENGTH_LONG).show()
}
}
}
//var buSelect:Button?=null
fun autoPlay(){
var buSelect:Button?=null
val emptyCells=ArrayList<Int>()
for ( cellID in 1..9){
if(!( player1.contains(cellID) || player2.contains(cellID))) {
emptyCells.add(cellID)
}
}
val r=Random()
val randIndex=r.nextInt(emptyCells.size-0)+0
val cellID= emptyCells[randIndex]
buSelect = when(cellID){
1-> bt1
2-> bt2
3-> bt3
4-> bt4
5-> bt5
6-> bt6
7-> bt7
8-> bt8
9-> bt9
else->{
bt1
}
}
//Thread.sleep(500)
PlayGame(
cellID,
buSelect!!
)
}
}
Could not execute method for android:onClick
also means, that something was wrong with the execution, meaning there was an exception thrown from your onClick listener.
In your case r.nextInt(emptyCells.size-0)+0
is the culprit. The bound has to be positive, but emptyCells
is empty and therefore emptyCells.size
is 0.
You'd have to handle this case before. Eventually your game is finished anyway.
fun autoPlay(){
var buSelect: Button? = null
val emptyCells = ArrayList<Int>()
for (cellID in 1..9) {
if (!(player1.contains(cellID) || player2.contains(cellID))) {
emptyCells.add(cellID)
}
}
// if all cells have been checked, the game is over
if (emptyCells.isEmpty()) return
val r = Random()
val randIndex = r.nextInt(emptyCells.size)
val cellID = emptyCells[randIndex]
buSelect = when(cellID) {
1 -> bt1
2 -> bt2
3 -> bt3
4 -> bt4
5 -> bt5
6 -> bt6
7 -> bt7
8 -> bt8
9 -> bt9
else -> {
bt1
}
}
//Thread.sleep(500)
PlayGame(
cellID,
buSelect!!
)
}
The issue is that you are calling with zero and it throws 并抛出
java.lang.IllegalArgumentException: bound must be positive
When your game ends ie when the last cell is clicked, all the cells will be consumed by both the player. So to avoid this error, simply add.
if(!emptyCells.isEmpty())
{
val randIndex=r.nextInt(emptyCells.size-0)+0
}
else
{
return
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.