在java中随机选择按钮

在java中随机选择按钮,java,random,jbutton,Java,Random,Jbutton,如何随机选择一个java按钮,我正在尝试创建一个tic-tac-toe游戏,用户在其中玩cpu或其他玩家。我有它的工作,为2名球员,但我卡在1名球员的游戏,我不知道它是否可以做到,但我的想法是,我只是随机选择一个按钮的cpu检查,看看它是否被选中之前,然后分配适当的x或o到选定的方块 public void buttonSelected(ActionEvent click) { Object source = click.getSource(); // loop throug

如何随机选择一个java按钮,我正在尝试创建一个tic-tac-toe游戏,用户在其中玩cpu或其他玩家。我有它的工作,为2名球员,但我卡在1名球员的游戏,我不知道它是否可以做到,但我的想法是,我只是随机选择一个按钮的cpu检查,看看它是否被选中之前,然后分配适当的x或o到选定的方块

public void buttonSelected(ActionEvent click) {

    Object source = click.getSource();

    // loop through to see which button has been selected
    if(onePlayer){ 


        // User Vs CPU
        /*if((turn % 2 == 0)){// CPU Turn
            int selected;
            do {
                selected = new Random().nextInt(btnEmpty.length );
                if (chosen[selected -1] == false){
                    chosen[selected -1] = true;
                }

            }while (chosen[selected -1] == true);

            source =  Integer.valueOf(selected);
            for(int i=1; i<= btnNotSelected.length; i++) {
                if(source == btnNotSelected[i] && turn < 10) {
                    btnClicked = true; // user has selected a button
                    // Check which user selected button and insert appropriate x or y
                    btnNotSelected[i].setText("X");
                    btnNotSelected[i].setEnabled(false); // disable selected button
                    pnlPlayingField.requestFocus(); // highlight selected panel 
                }   
            } 

        }
        else{ //User Turn
            for(int i=1; i<=9; i++) {
                if(source == btnNotSelected[i] && turn < 10) {
                    btnClicked = true; // user has selected a button
                    // Check which user selected button and insert O
                    btnNotSelected[i].setText("O");
                    btnNotSelected[i].setEnabled(false);
                    chosen[i] = true;// disable selected button
                    pnlPlayingField.requestFocus(); // highlight selected panel
                }
            }

        }  */
        turn++;  
    }

    else if(twoPlayer){
        for(int i=1; i<=9; i++) {
            if(source == btnNotSelected[i] && turn < 10) {
                btnClicked = true; // user has selected a button
                // Check which user selected button and insert appropriate x or y
                if(turn % 2 == 0){
                    btnNotSelected[i].setText("X");
                }
                else{
                    btnNotSelected[i].setText("O");
                }
                btnNotSelected[i].setEnabled(false); // disable selected button
                pnlPlayingField.requestFocus(); // highlight selected panel
                turn++;
    }`
public void按钮选中(ActionEvent单击){
对象源=单击.getSource();
//循环查看已选择的按钮
如果(一个玩家){
//用户与CPU
/*如果((回合%2==0)){//CPU回合
选择int;
做{
选定=新随机().nextInt(btnEmpty.length);
如果(已选择[已选择-1]==false){
已选择[已选择-1]=真;
}
}while(selected[selected-1]==true);
source=整数。valueOf(已选择);
对于(int i=1;i
上面的代码是一个无止境的循环,请将其更改为:

int selected;
do {
    selected = new Random().nextInt(btnEmpty.length);
}while (chosen[selected] == true);
chosen[selected] == true;

删除-1,因为nextInt(n)会给你一个“介于0(包括)和n(排除)”之间的数字。

我个人会从按钮的
列表开始,在每个按钮被选中时删除,这会更容易确定选择了什么和没有选择什么,但让我们来处理我们得到的

List<Integer> free = new ArrayList<Integer>(chosen.length);
for (int index = 0; index < chosen.length; index++) {
    if (!chosen[index]) {
        free.add(index);
    }
}

if (!free.isEmpty()) {
    Collections.shuffle(free);
    int selected = free.get(0);

    // Continue with game logic
}
List free=newarraylist(selected.length);
for(int index=0;index
基本上,这会将一个
整数
放在一个
列表
中,该列表表示“空闲”插槽。然后,我们使用
集合。无序移动
将列表随机化,然后我们抓取第一个元素(为了想要抓取的东西),并继续游戏逻辑


这消除了无限循环试图寻找不存在的空闲插槽的可能性…

一个单人井字游戏当然可以完成,并且您的随机选择策略很好。注释掉的单人代码中的第一个特定错误是无限的do while循环。循环上的条件始终计算为true因为
selected[selected-1]
始终为true(如果为false,则在条件检查之前将其设置为true),因此再次循环

您的do while应如下所示:

do {
    selected = new Random().nextInt(btnEmpty.length);
} while (chosen[selected - 1] == true);
chosen[selected - 1] = true;
这样,您就可以在while循环条件之后设置所选标志

我在onePlayer模块中看到了几个其他问题:

  • 在CPU turn块中,
    source
    (这里是一个整数)和
    btnNotSelected[i]
    (假设基于twoPlayer块中的工作代码的java按钮)之间的比较将不会像您期望的那样工作
  • 调用此方法是为了响应用户输入,即单击其中一个按钮。计算机不会提供任何此类输入,因此您应该有另一个触发器来调用运行计算机轮次代码。最简单的方法是在用户轮次后运行它
在不对总体编码风格和策略进行任何重大更改的情况下,我将尝试将onePlayer部分转换为更具功能性的内容:

public void buttonSelected(ActionEvent click) {

    Object source = click.getSource();

    if (onePlayer) {

        // User's turn first
        source.setText("O");
        source.setEnabled(false);
        pnlPlayingField.requestFocus();

        // Mark that button as chosen
        for (int i = 0; i < btnNotSelected.length; i++) {
            if (source == btnNotSelected[i]) {
                chosen[i] = true;
                break;
            }
        }

        // Increment turn counter
        turn++;

        // Check if game is over
        if (turn > 9) return;

        // CPU turn
        int selected;
        do {
            selected = new Random().nextInt(btnNotSelected.length);
        } while (chosen[selected]);

        chosen[selected] = true;
        btnNotSelected[selected].setText("X");
        btnNotSelected[selected].setEnabled(false);
        pnlPlayingField.requestFocus();
        turn++;

    } else if (twoPlayer) {
        /* your preexisting twoPlayer code */
    }

}
public void按钮选中(ActionEvent单击){
对象源=单击.getSource();
如果(一个玩家){
//先轮到用户
来源:setText(“O”);
source.setEnabled(false);
pnlPlayingField.requestFocus();
//将该按钮标记为选中状态
对于(int i=0;i9)返回;
//CPU转数
选择int;
做{
selected=new Random().nextInt(btnNotSelected.length);
}while(选择[选择]);
已选择[已选择]=真;
BtnotSelected[selected].setText(“X”);
BtnotSelected[selected].setEnabled(false);
pnlPlayingField.requestFocus();
turn++;
}else if(两人){
/*您先前存在的双人游戏代码*/
}
}

我不确定,但对我来说它看起来很不错。我认为你应该使用'selected'而不是'selected-1'作为索引。我会将所有空闲按钮放在一个列表中,洗牌,然后拖动t most元素。这消除了在没有空闲空间的情况下进入无限循环的可能性。这很好,只是我必须更改源代码。s将etText(“O”)改为((AbstractButton)source.setText(“O”);并将source.setEnabled(false)改为((组件)source.setEnabled(false);但我不明白为什么,Eclipse将其标记并自动更改。很高兴它成功了!这些强制转换错误的原因是
source
声明为type
Object
,而
Object
类没有
setText()
setEnabled()
方法。您用于按钮的类确实具有这些方法,因此修复该错误的更简洁的方法可能是将
源代码的类型更改为
抽象按钮(或用于按钮的任何类).Eclipse的修复非常方便,在这种情况下也可以使用,但是最好自己理解问题,以便了解代码的确切行为。
public void buttonSelected(ActionEvent click) {

    Object source = click.getSource();

    if (onePlayer) {

        // User's turn first
        source.setText("O");
        source.setEnabled(false);
        pnlPlayingField.requestFocus();

        // Mark that button as chosen
        for (int i = 0; i < btnNotSelected.length; i++) {
            if (source == btnNotSelected[i]) {
                chosen[i] = true;
                break;
            }
        }

        // Increment turn counter
        turn++;

        // Check if game is over
        if (turn > 9) return;

        // CPU turn
        int selected;
        do {
            selected = new Random().nextInt(btnNotSelected.length);
        } while (chosen[selected]);

        chosen[selected] = true;
        btnNotSelected[selected].setText("X");
        btnNotSelected[selected].setEnabled(false);
        pnlPlayingField.requestFocus();
        turn++;

    } else if (twoPlayer) {
        /* your preexisting twoPlayer code */
    }

}