bugfix> java > 投稿

私は自分の課題のためにシンプルなローリングダイスゲームを構築しようとしています。 2人のプレイヤーがいます。私のコードでは、メソッド getSource() を使用しようとしますプレイヤーが roll のときJButtonが有効になっている場合、他のプレイヤーのボタンは無効になりますが、ゲームを実行しても、両方のプレイヤーのボタンは有効のままです。ここに私のコードがあります:

Die.java

import java.util.*;
public class Die
{
    private final int MAX = 6;
    private int die1;
    Random rand = new Random();
    //Constructor
    public Die()
    {
        die1 = 1;
    }// end Constructor
    public int Roll()
    {
        die1 = rand.nextInt(MAX)+1;
        return die1;
    }
}

DisplaySixNumbersPanel.java

import java.awt.*;
import javax.swing.*;
public class DisplaySixNumbersPanel
{
    public static void main(String[ ] args) 
    {
        JFrame w1 = new JFrame("Six Numbers Game");
        w1.setLayout(new GridLayout(1,2));
        SixNumbersPanel2 player1 =new SixNumbersPanel2();
        SixNumbersPanel2 player2 =new SixNumbersPanel2();
        w1.add(player1);
        w1.add(player2);
        w1.setSize(540, 350);
        w1.setVisible(true);
        w1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    } //end main
} //end class

SixNumbersPanel2.java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class SixNumbersPanel2 extends JPanel implements ActionListener
{
    private JTextField text1;
    private boolean flag = false;
    private boolean checkflag[] = {false,false,false,false,false,false,false};
    private JLabel label;
    private JLabel label1;
    public JButton roll;
    private JButton restartButton;
    private JTextArea display;
    private JTextField[] fields = new JTextField[7];
    private Die dice = new Die();
    private int key;
    private int count;
    private int count1;
    private Player player1 = new Player();
    private Player player2 = new Player();
    private int check;
    private int[] list = new int [7];
    //private SixNumbersPanel2 player2panel;
    public SixNumbersPanel2()
    {
        label= new JLabel ("A number between 1 to 6 wil appear");
        label1 = new JLabel("once in each of the following textfields");
        roll = new JButton("Roll dice");
        restartButton = new JButton("Restart Game");
        text1 = new JTextField(3);
        display = new JTextArea(10,15);
        add(label);
        add(label1);
        for(int i=1;i<7;i++)
        {
            fields[i] = new JTextField(3);
            add(fields[i]);
        }
        add(roll);
        add(text1);
        add(display);
        display.setEditable(false);      
        restartButton.setVisible(false);
        add(restartButton);
        restartButton.addActionListener(this);
        roll.addActionListener(this);        
    }
    public void restart()
    {
       display.setText("");
       text1.setText("");
       for(int i=1; i<7; i++)
       {
           fields[i].setText("");
       }
       count=0;
       count1=0;
       Arrays.fill(checkflag,false);
       Arrays.fill(list,0);
       flag = false;
       restartButton.setVisible(false);
       rollenable(); 
    }

    public void actionPerformed(ActionEvent event)
    {
        if(event.getSource() == roll)
        {
            player2.rolldisable();
        }
        key=dice.Roll();
        count++;
        String toScreen= "Number of rolls: "+count;
        display.setText(toScreen);
        text1.setText(""+key);
        check = player1.Check(list,key);
        if(check < 0)
        {
            count1++;
            for(int i=1;i<7;i++)
            {
                if(key == i)
                {
                    list[i] = key;
                    checkflag[i]=true;
                    fields[i].setText(""+key);
                    if(checkflag[i] == true)
                    {
                        flag = true;
                        for(int a=1; a<7; a++)
                        {
                            if(checkflag[a]==false)
                            {
                                flag=false;
                            }
                        }
                    }
                }
                if(flag == true)
                {
                    display.setText("Congratulation, you have \ntaken "+count+" rolls to get one of \neach number between 1 and 6");
                    rolldisable();
                    restartButton.setVisible(true);                   
                }
            }
        }
        if(event.getSource() == restartButton)
        {
            restart();
        }
    }
    public void rollenable()
    {
        roll.setEnabled(true);
    }
    public void rolldisable()
    {
        roll.setEnabled(false);
    }
    public JButton getSubButton()
    {
        return this.roll;
    }
}

Player.java

import java.util.*;
import javax.swing.*;
public class Player
{
    private final int MAX = 100;
    private Die play = new Die();
    private boolean[] results = {false,false,false,false,false,false,false};
    private int count;
    private int key;
    private boolean check = false;
    //private JButton roll;
    public Player()
    {
        count=0;
        key=0;
    }
    public void Play()
    {
        for(int i=0;i<MAX;i++)
        {
            key=play.Roll();
            System.out.print("\nNumber rolled: "+key); 
            count++; 
            for(int a=1;a<7;a++)
            {
                if(a==key)
                {
                    results[a]=true;
                    System.out.print("\nSo far, you have rolled ");  
                    if(results[a]==true)
                    {
                        check=true;
                        for(int k=1;k<7;k++)
                        {
                            if(results[k] ==true)
                        {
                            System.out.print(" "+k+" ");
                        }
                        if(results[k] == false)
                        check=false;
                        }
                    }        
                }
            }  
            if(check==true)
            {
                System.out.print("\nCongratulations, you have taken "+count+" rolls to get one of each number between 1 and 6");
                break;
            }         
        }             
    }
    public int Check(int []check,int key)
    {
        int check1= Arrays.binarySearch(check,key);
        return check1;   
    }
    //public JButton getButton()
    //{
       // JButton button = null;
        //SixNumbersPanel2 roll = new SixNumbersPanel2();
        //return roll.roll = button;
    //}
    public void rolldisable() 
    {
        SixNumbersPanel2 dis = new SixNumbersPanel2();
        dis.getSubButton().setEnabled(false);
    }
}

また、 restartButton JButton、ゲーム全体を再起動するのではなく、クリックしたプレイヤーのみを再起動します。 GUI全体を再起動する方法としての提案は素晴らしいでしょう。

すべての助けをいただければ幸いです。

回答 1 件
  • この...

    public void rolldisable() 
    {
        SixNumbersPanel2 dis = new SixNumbersPanel2();
        dis.getSubButton().setEnabled(false);
    }
    
    

    間違っています、基本的には SixNumbersPanel2 の新しいインスタンスを作成しています  そして、その状態を変更しようとしていますが、実際には画面に表示されず、画面に表示されるものとは何の関係もありません。

    このソリューションは単純なものではありません。必要なのは、 SixNumbersPanel2 の2つのインスタンス間で共有できる何らかのモデル/コントローラーです  そして、それらが応答できる適切な状態イベントを生成します。

    どのプレイヤーがどのプレイヤーであるかを識別する方法を考案する必要がありますので、各 SixNumbersPanel2  どのプレーヤーを表し、どのプレーヤーが現在アクティブかを知っている

    更新しました...

    必要な機能変更を実装するには、コア機能を管理し、状態が何らかの意味で変化した場合に通知/イベントを生成できる(「次のプレイヤー」のように)何らかの「中央」ハブが必要です。

    大まかに言えば、これらは以下によってカバーされます。

    モデルビューコントローラー

    オブザーバーパッテン

    最初に、プレイヤーを区別するために、何らかのトークンで開始する必要があります...

    enum Player {
        ONE, TWO;
    }
    
    

    次に、データとコア機能を管理するために使用されるある種の「モデル」が必要です

    public interface SixNumbersModel {        
        public Player getCurrentTurn();        
        public Player nextTurn();        
        public int roll();        
        public boolean hasWon(Player player);        
        public Set<Integer> getPlayerResults(Player player);
        public int getTurnsCount(Player player);        
        public void addChangeListener(ChangeListener listener);
        public void removeChangeListener(ChangeListener listener);
    }
    
    

    nb:実際に結果を管理する「プレーヤーモデル」を使用できますが、私は怠け者です

    私が interface で始めた理由  モデルのユーザーは、モデルの実装方法を気にするべきではありません(実装により、各プレーヤーの結果の管理が個々のモデルに分離される場合がありますが、 SixNumbersModel のユーザー  気にしない)

    public class DefaultSizeNumbersModel implements SixNumbersModel {
        private List<ChangeListener> changeListeners;
        private Die die = new Die();
        private Player turn;
        private Map<Player, Set<Integer>> results;
        private Map<Player, Integer> turns;
        public DefaultSizeNumbersModel() {
            changeListeners = new ArrayList<>(2);
            results = new HashMap<>();
            results.put(Player.ONE, new HashSet<>(6));
            results.put(Player.TWO, new HashSet<>(6));
            turns = new HashMap<>(2);
            turns.put(Player.ONE, 0);
            turns.put(Player.TWO, 0);
            setCurrentTurn(Player.ONE);
        }
        @Override
        public Player getCurrentTurn() {
            return turn;
        }
        protected void setCurrentTurn(Player player) {
            turn = player;
        }
        @Override
        public Player nextTurn() {
            switch (getCurrentTurn()) {
                case ONE:
                    setCurrentTurn(Player.TWO);
                    break;
                case TWO:
                    setCurrentTurn(Player.ONE);
                    break;
                default:
                    setCurrentTurn(Player.ONE);
                    break;
            }
            fireStateChanged();
            return getCurrentTurn();
        }
        @Override
        public int roll() {
            incrementTurnCount(getCurrentTurn());
            int result = die.Roll();
            Set<Integer> playerResults = results.get(getCurrentTurn());
            playerResults.add(result);
            return result;
        }
        @Override
        public boolean hasWon(Player player) {
            Set<Integer> playerResults = results.get(getCurrentTurn());
            return playerResults.size() == 5; // 0...5
        }
        @Override
        public Set<Integer> getPlayerResults(Player player) {
            Set<Integer> actualResults = results.get(player);
            Set<Integer> copy = new HashSet<>(actualResults);
            return copy;
        }
        @Override
        public int getTurnsCount(Player player) {
            return turns.get(player);
        }
        protected void setTurnsCount(Player player, int count) {
            turns.put(player, count);
        }
        protected void incrementTurnCount(Player player) {
            int count = getTurnsCount(player);
            count++;
            setTurnsCount(player, count);
        }
        @Override
        public void addChangeListener(ChangeListener listener) {
            changeListeners.add(listener);
        }
        @Override
        public void removeChangeListener(ChangeListener listener) {
            changeListeners.remove(listener);
        }
        protected void fireStateChanged() {
            ChangeEvent evt = new ChangeEvent(this);
            for (ChangeListener listener : changeListeners) {
                listener.stateChanged(evt);
            }
        }
    }
    
    

    次に、ある種の「ビュー」が必要です...

    public class SixNumbersPanel extends JPanel {
        private Player player;
        private SixNumbersModel model;
        private JButton roll;
        private JTextArea ta;
        public SixNumbersPanel(Player player, SixNumbersModel model) {
            this.player = player;
            this.model = model;
            model.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    roll.setEnabled(player == model.getCurrentTurn());
                }
            });
            roll = new JButton("Roll");
            ta = new JTextArea(5, 10);
            roll.setEnabled(player == model.getCurrentTurn());
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(new JLabel(player.name()), gbc);
            add(roll, gbc);
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(new JScrollPane(ta), gbc);
            roll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int result = model.roll();
                    ta.append(Integer.toString(result) + "\n");
                    if (model.hasWon(player)) {
                        JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
                    }
                    model.nextTurn();
                }
            });
        }
    }
    
    

    さて、非常に基本的なものですが、ボタンとテキスト領域があります。状態が変化したときに通知されるモデルへの関心を登録し、それが表すプレーヤーが現在のプレーヤーである場合にのみボタンが有効になるようにします。

    実行可能な例...
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    import java.util.Set;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    public class Test {
        public static void main(String[] args) {
            new Test();
        }
        enum Player {
            ONE, TWO;
        }
        public interface SixNumbersModel {
            public Player getCurrentTurn();
            public Player nextTurn();
            public int roll();
            public boolean hasWon(Player player);
            public Set<Integer> getPlayerResults(Player player);
            public int getTurnsCount(Player player);
            public void addChangeListener(ChangeListener listener);
            public void removeChangeListener(ChangeListener listener);
        }
        public class DefaultSizeNumbersModel implements SixNumbersModel {
            private List<ChangeListener> changeListeners;
            private Die die = new Die();
            private Player turn;
            private Map<Player, Set<Integer>> results;
            private Map<Player, Integer> turns;
            public DefaultSizeNumbersModel() {
                changeListeners = new ArrayList<>(2);
                results = new HashMap<>();
                results.put(Player.ONE, new HashSet<>(6));
                results.put(Player.TWO, new HashSet<>(6));
                turns = new HashMap<>(2);
                turns.put(Player.ONE, 0);
                turns.put(Player.TWO, 0);
                setCurrentTurn(Player.ONE);
            }
            @Override
            public Player getCurrentTurn() {
                return turn;
            }
            protected void setCurrentTurn(Player player) {
                turn = player;
            }
            @Override
            public Player nextTurn() {
                switch (getCurrentTurn()) {
                    case ONE:
                        setCurrentTurn(Player.TWO);
                        break;
                    case TWO:
                        setCurrentTurn(Player.ONE);
                        break;
                    default:
                        setCurrentTurn(Player.ONE);
                        break;
                }
                fireStateChanged();
                return getCurrentTurn();
            }
            @Override
            public int roll() {
                incrementTurnCount(getCurrentTurn());
                int result = die.Roll();
                Set<Integer> playerResults = results.get(getCurrentTurn());
                playerResults.add(result);
                return result;
            }
            @Override
            public boolean hasWon(Player player) {
                Set<Integer> playerResults = results.get(getCurrentTurn());
                return playerResults.size() == 5; // 0...5
            }
            @Override
            public Set<Integer> getPlayerResults(Player player) {
                Set<Integer> actualResults = results.get(player);
                Set<Integer> copy = new HashSet<>(actualResults);
                return copy;
            }
            @Override
            public int getTurnsCount(Player player) {
                return turns.get(player);
            }
            protected void setTurnsCount(Player player, int count) {
                turns.put(player, count);
            }
            protected void incrementTurnCount(Player player) {
                int count = getTurnsCount(player);
                count++;
                setTurnsCount(player, count);
            }
            @Override
            public void addChangeListener(ChangeListener listener) {
                changeListeners.add(listener);
            }
            @Override
            public void removeChangeListener(ChangeListener listener) {
                changeListeners.remove(listener);
            }
            protected void fireStateChanged() {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : changeListeners) {
                    listener.stateChanged(evt);
                }
            }
        }
        public class Die {
            private final int MAX = 6;
            private int die1;
            Random rand = new Random();
            //Constructor
            public Die() {
                die1 = 1;
            }// end Constructor
            public int Roll() {
                die1 = rand.nextInt(MAX) + 1;
                return die1;
            }
        }
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame("Roll Six");
                    frame.setLayout(new GridLayout(2, 0));
                    SixNumbersModel model = new DefaultSizeNumbersModel();
                    SixNumbersPanel onePane = new SixNumbersPanel(Player.ONE, model);
                    SixNumbersPanel twoPane = new SixNumbersPanel(Player.TWO, model);
                    frame.add(onePane);
                    frame.add(twoPane);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
        public class SixNumbersPanel extends JPanel {
            private Player player;
            private SixNumbersModel model;
            private JButton roll;
            private JTextArea ta;
            public SixNumbersPanel(Player player, SixNumbersModel model) {
                this.player = player;
                this.model = model;
                model.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        roll.setEnabled(player == model.getCurrentTurn());
                    }
                });
                roll = new JButton("Roll");
                ta = new JTextArea(5, 10);
                roll.setEnabled(player == model.getCurrentTurn());
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(new JLabel(player.name()), gbc);
                add(roll, gbc);
                gbc.weightx = 1;
                gbc.weighty = 1;
                gbc.fill = GridBagConstraints.BOTH;
                add(new JScrollPane(ta), gbc);
                roll.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int result = model.roll();
                        ta.append(Integer.toString(result) + "\n");
                        if (model.hasWon(player)) {
                            JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
                        }
                        model.nextTurn();
                    }
                });
            }
        }
    }
    
    

あなたの答え