diff --git a/src/main/java/controls/PhaseController.java b/src/main/java/controls/PhaseController.java new file mode 100644 index 0000000..8a1cabb --- /dev/null +++ b/src/main/java/controls/PhaseController.java @@ -0,0 +1,127 @@ +package controls; + +import interfaces.IGameView; +import resources.Algo; + +public class PhaseController { + IGameView iGameView; + Phase currentPhase; + int guess; + boolean isDecidedAttacker; + int attacker; + int target; + Algo algo; + public AbstractGameState abstractGameState; + TurnPlayer turnPlayer; + TurnBot turnBot; + public PhaseController(Algo algo){ + this.algo = algo; + isDecidedAttacker = false; + turnPlayer = new TurnPlayer(algo); + turnBot = new TurnBot(algo); + abstractGameState = turnPlayer; + currentPhase=Phase.Selection; + } + public void bindGameView(IGameView iGameView){ + this.iGameView = iGameView; + } + public void startGame(){ + changePhase(Phase.StartPlayerTurn); + } + public void setSelection(int attacker){ + changePhase(Phase.Selection, attacker); + } + public void setTarget(int target){ + changePhase(Phase.Target, target); + + } + public boolean isDecidedAttacker(){ + return isDecidedAttacker; + } + /** + * + * @param phase 遷移先の状態 + * @param params 遷移先に遷移するために必要な引数 + */ + private void changePhase(Phase phase, int... params) { + + switch (phase){ + case StartPlayerTurn: + abstractGameState=turnPlayer; + isDecidedAttacker = !abstractGameState.isDeckLess(); + iGameView.repaintBoard(abstractGameState); + iGameView.onStartPlayerTurn(abstractGameState); + break; + case Selection: + + this.attacker = params[0]; + isDecidedAttacker = true; + currentPhase = Phase.Target; + iGameView.onDecidedSelection(attacker); + + break; + case Target: + this.target = params[0]; + currentPhase = phase; + iGameView.onDecidedTarget(target); + currentPhase = Phase.Declaration; + + break; + case Declaration: + this.guess = params[0]; + abstractGameState.attack(this.guess,this.attacker,this.target); + currentPhase = Phase.StartBotTurn; + var isSucceed = abstractGameState.isSucceedLatestAttack(); + iGameView.repaintBoard(abstractGameState); + iGameView.onFinishedPlayerAttack(guess, isSucceed); + if(judgeGameOver())return; + changePhase(Phase.StartBotTurn, 0); + break; + case StartBotTurn: + + currentPhase = Phase.StartBotTurn; + abstractGameState = turnBot; + abstractGameState.updateTurn(); + iGameView.onStartBotAttack(turnBot); + + break; + case BotAttack: + abstractGameState.updateTurn(); + abstractGameState.attack(params[0],params[1],params[2]); + iGameView.onFinishedBotAttack(params[0], abstractGameState.isSucceedLatestAttack()); + if(judgeGameOver())return; + changePhase(Phase.StartPlayerTurn); + break; + + } + } + + public void setDeclaration(int guess) { + changePhase(Phase.Declaration, guess); + } + public void botAttack(int guess, int attacker, int target){ + changePhase(Phase.BotAttack,guess,attacker,target); + + + } + boolean judgeGameOver(){ + + if(algo.getLoseA()){ + iGameView.onFinishedGame(abstractGameState, true); + return true; + }else if(algo.getLoseB()){ + iGameView.onFinishedGame(abstractGameState,false); + return true; + } + return false; + } + + enum Phase{ + StartPlayerTurn, + Selection, + Target, + Declaration, + StartBotTurn, + BotAttack + } +} diff --git a/src/main/java/interfaces/IGameView.java b/src/main/java/interfaces/IGameView.java new file mode 100644 index 0000000..34cfaae --- /dev/null +++ b/src/main/java/interfaces/IGameView.java @@ -0,0 +1,51 @@ +package interfaces; + +import controls.AbstractGameState; +import controls.TurnBot; + +public interface IGameView { + void onStartPlayerTurn(AbstractGameState abstractGameState); + /** + * アタックに使用するカードが決定した際に実行 + * @param selection + */ + void onDecidedSelection(int selection); + /** + * アタックの対象が決定した際に実行 + * @param target + */ + void onDecidedTarget(int target); + + /** + * プレイヤーのアタックが終了した際に実行 + * @param guess 宣言した数 + * @param isSucceed アタックの成否の結果 + */ + void onFinishedPlayerAttack(int guess, boolean isSucceed); + + /** + * ボットのアタックが開始した際に実行 + * + * @param turnBot ボットの思考結果を出力するためのAI + */ + void onStartBotAttack(TurnBot turnBot); + + /** + * ボットのアタックが終了した際に実行 + * + * @param guess + * @param isSucceed アタックの成否の結果 + */ + void onFinishedBotAttack(int guess, boolean isSucceed); + + /** + * ゲームが終了した際に実行 + */ + void onFinishedGame(AbstractGameState abstractGameState, boolean isLoseA); + + /** + * 盤面を再描画する + * @param abstractGameState + */ + void repaintBoard(AbstractGameState abstractGameState); +} diff --git a/src/main/java/views/CardButton.java b/src/main/java/views/CardButton.java index 10b5b49..1eadaf1 100644 --- a/src/main/java/views/CardButton.java +++ b/src/main/java/views/CardButton.java @@ -29,6 +29,10 @@ } } + public Status getStatus() { + return status; + } + public void setStatus(Status status) { switch (status) { case OPEN: @@ -45,6 +49,7 @@ this.setForeground(OPEN_COLOR); break; } + this.status = status; } @Override diff --git a/src/main/java/views/HandButtons.java b/src/main/java/views/HandButtons.java new file mode 100644 index 0000000..d0b86a5 --- /dev/null +++ b/src/main/java/views/HandButtons.java @@ -0,0 +1,28 @@ +package views; + +import java.awt.event.ActionListener; +import java.util.ArrayList; + +/** + * 手札の情報をボタンで扱うためのクラス + */ +class HandButtons extends ArrayList { + public void addListeners(ActionListener al){ + for (var hb : this){ + hb.addActionListener(al); + } + } + public void setEnableButtons(boolean enableButtons){ + for (var hb : this){ + hb.setEnabled(enableButtons); + } + } + public void removeButtonListeners(){ + for(var my:this) { + for( ActionListener al : my.getActionListeners() ) { + my.removeActionListener( al ); + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/views/MainFrame.java b/src/main/java/views/MainFrame.java index ddc4797..f69bab9 100644 --- a/src/main/java/views/MainFrame.java +++ b/src/main/java/views/MainFrame.java @@ -1,6 +1,6 @@ package views; -import controls.StepScheduler; +import controls.PhaseController; import resources.Algo; import javax.swing.*; @@ -9,20 +9,25 @@ import java.awt.event.WindowListener; public class MainFrame extends JFrame { - StepScheduler stepScheduler; public MainFrame() { super("Algolike"); - var mainPanel = new MainPanel(new Algo()); - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + var algo = new Algo(); + var mainPanel = new MainPanel(algo); + var phaseController = new PhaseController(algo); + mainPanel.bindPhaseController(phaseController); + phaseController.bindGameView(mainPanel); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainPanel.setVisible(true); + this.add(mainPanel, BorderLayout.CENTER); this.pack(); + this.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { - mainPanel.playerBehave(); + phaseController.startGame(); } @Override @@ -47,7 +52,6 @@ @Override public void windowActivated(WindowEvent e) { - } @Override diff --git a/src/main/java/views/MainPanel.java b/src/main/java/views/MainPanel.java index 5901ecb..2cc785d 100644 --- a/src/main/java/views/MainPanel.java +++ b/src/main/java/views/MainPanel.java @@ -1,53 +1,32 @@ package views; import controls.*; -import interfaces.IAttack; +import interfaces.IGameView; import resources.Algo; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.List; import static java.lang.Integer.parseInt; import static views.Constants.*; -public class MainPanel extends JPanel { - private List myHandButtons; - - private List opponentHandButtons; - - private List selectableMyHandKeys; - private List selectableOpponentHandKeys; - Constants.Step currentStep; +public class MainPanel extends JPanel implements IGameView { JPanel myHandButtonsPanel; JPanel myHandAttackerPanel; JPanel myPanel; JPanel opponentButtonsPanel; JPanel opponentAttackerPanel; JPanel opponentPanel; - AbstractGameState abstractGameState; - TurnPlayer turnPlayer; - TurnBot turnBot; - /** - * アタックで使用するカードが既に決定しているか - */ - boolean isDecidedAttacker; - int guess; - int attacker; - int target; - int indexForMyHands = 0; - int indexForOpponent = 0; + PhaseController phaseController; + private HandButtons myHandButtons; + private HandButtons opponentHandButtons; private JPanel deckButtonPanel; - public MainPanel(Algo algo) { super(new BorderLayout()); - myHandButtons = new ArrayList<>(); - opponentHandButtons = new ArrayList<>(); - selectableOpponentHandKeys = new ArrayList<>(); - currentStep = Step.SelectMyHands; + myHandButtons = new HandButtons(); + opponentHandButtons = new HandButtons(); deckButtonPanel = new JPanel(); myHandButtonsPanel = new JPanel(); @@ -55,53 +34,165 @@ myHandAttackerPanel = new JPanel(); myPanel = new JPanel(); + opponentAttackerPanel = new JPanel(); opponentPanel = new JPanel(); + phaseController = new PhaseController(algo); + myPanel.add(myHandAttackerPanel); myPanel.add(myHandButtonsPanel); opponentPanel.add(opponentAttackerPanel); opponentPanel.add(opponentButtonsPanel); - turnPlayer = new TurnPlayer(algo); - turnBot = new TurnBot(algo); - abstractGameState= turnPlayer; - - if (!abstractGameState.isDeckLess()) { //デッキが存在する場合 - var cardButton = new JButton("deck"); - cardButton.setPreferredSize(new Dimension(CARD_HEIGHT, CARD_WIDTH)); - deckButtonPanel.add(cardButton); - } - - repaintField(); - /** - * setButton末尾にあった処理をコンストラクタ内へ。 - * - */ add(deckButtonPanel, BorderLayout.WEST); - //add(myHandButtonsPanel, BorderLayout.SOUTH); add(myPanel, BorderLayout.SOUTH); - - //add(opponentButtonsPanel, BorderLayout.NORTH); add(opponentPanel, BorderLayout.NORTH); - opponentHandButtons.stream().filter(x -> x.getText().equals(CLOSED_SYMBOL)).forEach(x -> { - x.setEnabled(true); - }); + + updateOpponentHandButtons(); repaint(); } + public void bindPhaseController(PhaseController phaseController){ + this.phaseController = phaseController; + } + void updateMyHandButtons() { + /** + * 自分の手札のボタンにリスナーを追加する処理 + */ + myHandButtons.removeButtonListeners(); + myHandButtons.setEnableButtons(true); + myHandButtons.addListeners(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + var sourceButton = ((CardButton) e.getSource()); + var isOpened = sourceButton.getStatus()== CardButton.Status.OPEN; + if(isOpened){ + JOptionPane.showMessageDialog(null, "裏のカードを選んでください. ", "Warn", + JOptionPane.WARNING_MESSAGE); + return; + } - void botBehave() { - abstractGameState = turnBot; - abstractGameState.updateTurn(); + for (var my : MainPanel.this.myHandButtons) my.setEnabledSelection(false); + sourceButton.setEnabledSelection(true); + var option = JOptionPane.showConfirmDialog(null, "このカードを使ってアタックをしますか?", "confirmation", 2); + if (option == JOptionPane.YES_OPTION) { + int attacker = myHandButtons.indexOf(sourceButton); + phaseController.setSelection(attacker); + } else { + sourceButton.setEnabledSelection(false); + } + + } + }); + } + + void updateOpponentHandButtons() { + /** + * 相手の手札を選択する処理をリスナーに追加する + */ + opponentHandButtons.removeButtonListeners(); + opponentHandButtons.addListeners(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(!phaseController.isDecidedAttacker()){ + JOptionPane.showMessageDialog(null, "あなたの手札からアタックに使用するカードを選んでください. ", "Warn", + JOptionPane.WARNING_MESSAGE); + return; + } + var sourceButton = ((CardButton) e.getSource()); + var index = opponentHandButtons.indexOf(sourceButton); + sourceButton.setEnabledSelection(true); + //相手のカードを選択したときに確認用ダイアログを出す + var option = JOptionPane.showConfirmDialog(null, "このカードを選びますか?", "confirmation", 2); + if (option == JOptionPane.YES_OPTION) { + phaseController.setTarget(index); + } else { + sourceButton.setEnabledSelection(false); + } + } + }); + } + + void paintDrawCard(AbstractGameState abstractGameState) { + var deckTopCard = abstractGameState.getTopCard(); + + if (!abstractGameState.isDeckLess()) { //デッキが存在する場合にデッキトップのカードを表示する処理 + var cardButton = new CardButton(deckTopCard.getKey().toString()); + cardButton.setBounds(0, 100, CARD_WIDTH, CARD_HEIGHT); + if (abstractGameState.isATurn()) { + myHandAttackerPanel.add(cardButton); + } else { + cardButton.setText(CLOSED_SYMBOL); + opponentAttackerPanel.add(cardButton); + } + if (abstractGameState.getDeckNumber() == 1) { + deckButtonPanel.removeAll(); + } + }else{ + updateMyHandButtons(); + } + + validate(); + repaint(); + } + @Override + public void onStartPlayerTurn(AbstractGameState abstractGameState) { + JOptionPane.showMessageDialog(null, "あなたのターンです。"); + var selectText = !abstractGameState.isDeckLess() + ? "あなたは数字\"" + abstractGameState.getTopCard().getKey() + "\"のカードをドローしました。" + : "アタックに使用するカードを手札から選んでください。"; + + paintDrawCard(abstractGameState); + if (!abstractGameState.isDeckLess()) { + selectText ="あなたは数字\"" + abstractGameState.getTopCard().getKey() + "\"のカードをドローしました。"; + phaseController.setSelection(0); + }else { + selectText = "アタックに使用するカードを手札から選んでください。"; + } + JOptionPane.showMessageDialog(null, selectText); + + } + @Override + public void onDecidedSelection(int attacker) { + } + @Override + public void onDecidedTarget(int target) { + String[] optionsToChoose = new String[DECK_COUNT]; + for (var i = 0; i < optionsToChoose.length; i++) optionsToChoose[i] = String.valueOf(i); + var getDeclaredNumber = (String) JOptionPane.showInputDialog( + null, + "このカードの数字を宣言してください。", + "Declare Number", + JOptionPane.QUESTION_MESSAGE, + null, + optionsToChoose, + optionsToChoose[0]); + + if (getDeclaredNumber != null) { //数字を宣言して、承認したとき + var g = parseInt(getDeclaredNumber); + phaseController.setDeclaration(g); + } else { + opponentHandButtons.get(target).setEnabledSelection(false); + } + } + @Override + public void onFinishedPlayerAttack(int guess, boolean isSucceed) { + String resultMessage = "あなたのアタックは"; + resultMessage += isSucceed ? "成功しました。" : "失敗しました。"; + resultMessage += "(宣言した値:" + guess + ")"; + JOptionPane.showMessageDialog(null, resultMessage); + } + + @Override + public void onStartBotAttack(TurnBot turnBot) { var bot = new BotIntelligence(turnBot); - JOptionPane.showMessageDialog(null, "Botのターンです。"); var selectText = ""; var atk = 0; - if (!abstractGameState.isDeckLess()) { //デッキにカードが存在するとき - paintDrawCard();//デッキから引いたカードを描画する + if (!turnBot.isDeckLess()) { //デッキにカードが存在するとき + paintDrawCard(turnBot);//デッキから引いたカードを描画する selectText = "Botはカードをドローしました。"; } else { atk = bot.selectAttacker(); @@ -119,54 +210,39 @@ var dec = bot.declareNumber(tar); JOptionPane.showMessageDialog(null, "Botは\"" + dec + "\"を宣言しました。"); - abstractGameState.attack(dec, atk, tar); - boolean isSucceed = abstractGameState.isSucceedLatestAttack(); + phaseController.botAttack(dec, atk, tar); +// boolean isSucceed = abstractGameState.isSucceedLatestAttack(); +// +// String resultMessage = "Botのアタックは "; +// resultMessage += isSucceed ? "成功しました。" : "失敗しました。"; +// JOptionPane.showMessageDialog(null, resultMessage); +// +// myHandButtons.get(tar).setEnabledSelection(false); +// repaintField(); +// if (isGameOver()) { +// finishGame(); +// return; +// } +// abstractGameState.updateTurn(); + } - String resultMessage = "Botのアタックは "; + @Override + public void onFinishedBotAttack(int guess, boolean isSucceed) { + String resultMessage = "Botのアタックは"; resultMessage += isSucceed ? "成功しました。" : "失敗しました。"; + resultMessage += "(宣言した値:" + guess + ")"; JOptionPane.showMessageDialog(null, resultMessage); - myHandButtons.get(tar).setEnabledSelection(false); - repaintField(); - if (isGameOver()) { - finishGame(); - return; - } - abstractGameState.updateTurn(); - playerBehave(); } - - void paintDrawCard() { - var deckTopCard = abstractGameState.getTopCard(); - - if (!abstractGameState.isDeckLess()) { //デッキが存在する場合にデッキトップのカードを表示する処理 - var cardButton = new CardButton(deckTopCard.getKey().toString()); - cardButton.setBounds(0, 100, CARD_WIDTH, CARD_HEIGHT); - if (abstractGameState.isATurn()) { - myHandAttackerPanel.add(cardButton); - isDecidedAttacker = true; - } else { - cardButton.setText(CLOSED_SYMBOL); - opponentAttackerPanel.add(cardButton); - } - if (abstractGameState.getDeckNumber() == 1) { - deckButtonPanel.removeAll(); - } - } - - validate(); - repaint(); - } - - void repaintField() { - + @Override + public void repaintBoard(AbstractGameState abstractGameState) { var myHands = abstractGameState.getMyHands(); var opponentHands = abstractGameState.getOpponentHands(); /** * 初期化処理(する必要があるのかどうかは知らない) */ - isDecidedAttacker = false; + deckButtonPanel.removeAll(); myHandButtonsPanel.removeAll();// myHandButtons.clear(); myHandAttackerPanel.removeAll(); @@ -174,199 +250,44 @@ opponentButtonsPanel.removeAll();// opponentHandButtons.clear(); - /** - * 自分の手札に関する処理 - */ - indexForMyHands = 0; + if (!abstractGameState.isDeckLess()) { //デッキが存在する場合 + var cardButton = new JButton("deck"); + cardButton.setPreferredSize(new Dimension(CARD_HEIGHT, CARD_WIDTH)); + deckButtonPanel.add(cardButton); + } for (var i : myHands) { var cardButton = new CardButton(i.getKey().toString()); cardButton.setStatus(i.getValue() ? CardButton.Status.OPEN : CardButton.Status.MY_CLOSED); - myHandButtons.add(cardButton); - //myHandButtonsPanel.add(cardButton, BorderLayout.WEST); myHandButtonsPanel.add(cardButton); - final var a = indexForMyHands;//actionPerformedの中に書くと、クリックされて初めて、回しきったindexForMyHandsを参照してしまうため、ここで一時変数に格納する - cardButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (!abstractGameState.isDeckLess()) return;//デッキがあるときは何も反応しないように - for (var my : myHandButtons) my.setEnabledSelection(false); - cardButton.setEnabledSelection(true); - var option = JOptionPane.showConfirmDialog(null, "このカードを使ってアタックをしますか?", "confirmation", 2); - - - if (option == JOptionPane.YES_OPTION) { - attacker = a; - isDecidedAttacker = true; - } else { - cardButton.setEnabledSelection(false); - } - } - }); - indexForMyHands++; } //ここまでが自分のカードに関する処理 /** *相手のカードに関する処理 */ - indexForOpponent = 0; - for (var i : opponentHands) { - var cardButton = new CardButton(i.getValue() ? i.getKey().toString() : CLOSED_SYMBOL); - cardButton.setStatus(i.getValue() ? CardButton.Status.OPEN : CardButton.Status.CLOSED); - cardButton.setEnabled(!i.getValue()); - cardButton.addActionListener(new ActionListener() { - final int index = indexForOpponent; - - public void actionPerformed(ActionEvent e) { - if (!abstractGameState.isDeckLess()) isDecidedAttacker = true; - if (!isDecidedAttacker) { - JOptionPane.showMessageDialog(null, "あなたの手札からアタックに使用するカードを選んでください. ", "Warn", - JOptionPane.WARNING_MESSAGE); - return; - } - - cardButton.setEnabledSelection(true); - - //相手のカードを選択したときに確認用ダイアログを出す - var option = JOptionPane.showConfirmDialog(null, "このカードを選びますか?", "confirmation", 2); - if (option == JOptionPane.YES_OPTION) { - target = opponentHands.size() - index;//画面上,相手の手札も自分の手札と同じように左から右へ並べられているため,それを補正するために反転させている - var t = index; - opponentHandButtons.stream().filter(x -> x.getText().equals(CLOSED_SYMBOL)).forEach(x -> { - x.setEnabled(false); - }); - String[] optionsToChoose = new String[DECK_COUNT]; - for (var i = 0; i < optionsToChoose.length; i++) optionsToChoose[i] = String.valueOf(i); - var getDeclaredNumber = (String) JOptionPane.showInputDialog( - null, - "このカードの数字を宣言してください。", - "Declare Number", - JOptionPane.QUESTION_MESSAGE, - null, - optionsToChoose, - optionsToChoose[0]); - if (getDeclaredNumber != null) { //数字を宣言して、承認したとき - guess = Integer.parseInt(getDeclaredNumber); - var g = Integer.parseInt(getDeclaredNumber); - abstractGameState.attack(g, attacker, t); - - boolean isSucceed = abstractGameState.isSucceedLatestAttack(); - - String resultMessage = "あなたのアタックは"; - resultMessage += isSucceed ? "成功しました。" : "失敗しました。"; - JOptionPane.showMessageDialog(null, resultMessage); - } else { - opponentHandButtons.stream().filter(x -> x.getText().equals(CLOSED_SYMBOL)).forEach(x -> { - x.setEnabled(true); - }); - return; - } - - } else { - cardButton.setEnabledSelection(false); - return; - } - for (var my : myHandButtons) my.setEnabledSelection(false); - cardButton.setEnabledSelection(false); - repaintField(); - if (isGameOver()) { - finishGame(); - return; - } - botBehave(); - } - }); - opponentHandButtons.add(cardButton); - opponentButtonsPanel.add(cardButton, 0);//見た目の順序が逆になるように,0番目に挿入 - indexForOpponent++; - } - //ここまでが相手のカードに関する処理 - validate(); - repaint(); - } - - public void playerBehave() { - abstractGameState = turnPlayer; - isDecidedAttacker = false; - JOptionPane.showMessageDialog(null, "あなたのターンです。"); - var selectText = ""; - var atk = 0; - if (!abstractGameState.isDeckLess()) { //デッキにカードが存在するとき - selectText = "あなたは数字\"" + abstractGameState.getTopCard().getKey() + "\"のカードをドローしました。"; - } else { - selectText = "アタックに使用するカードを手札から選んでください。"; - } - paintDrawCard(); - - JOptionPane.showMessageDialog(null, selectText); - - if (!abstractGameState.isDeckLess()) JOptionPane.showMessageDialog(null, "アタックする対象を相手の手札から選んでください。"); - - } - - /** - * ゲームが終了しているか - * - * */ - boolean isGameOver() { - - if (abstractGameState.isALose()) { - return true; - } else if (abstractGameState.isBLose()) { - return true; - } - - return false; - } - - void finishGame() { - var myHands = abstractGameState.getMyHands(); - var opponentHands = abstractGameState.getOpponentHands(); - - /** - * 初期化処理(する必要があるのかどうかは知らない) - */ - isDecidedAttacker = false; - myHandButtonsPanel.removeAll();// - myHandButtons.clear(); - opponentButtonsPanel.removeAll();// - opponentHandButtons.clear(); - /** - * 自分の手札に関する処理 - */ - indexForMyHands = 0; - for (var i : myHands) { - var cardButton = new CardButton(i.getKey().toString()); - cardButton.setStatus(i.getValue() ? CardButton.Status.OPEN : CardButton.Status.MY_CLOSED); - myHandButtons.add(cardButton); - myHandButtonsPanel.add(cardButton, BorderLayout.WEST); - - final var a = indexForMyHands;//actionPerformedの中に書くと、クリックされて初めて、回しきったindexForMyHandsを参照してしまうため、ここで一時変数に格納する - indexForMyHands++; - } - //ここまでが自分のカードに関する処理 - - /** - *相手のカードに関する処理 - */ - indexForOpponent = 0; for (var i : opponentHands) { var cardButton = new CardButton(i.getValue() ? i.getKey().toString() : CLOSED_SYMBOL); cardButton.setStatus(i.getValue() ? CardButton.Status.OPEN : CardButton.Status.CLOSED); cardButton.setEnabled(!i.getValue()); opponentHandButtons.add(cardButton); opponentButtonsPanel.add(cardButton, 0);//見た目の順序が逆になるように,0番目に挿入 - indexForOpponent++; } + + updateOpponentHandButtons(); //ここまでが相手のカードに関する処理 validate(); repaint(); - if (abstractGameState.isALose()) { + } + @Override + public void onFinishedGame(AbstractGameState abstractGameState, boolean isLoseA) { + this.repaintBoard(abstractGameState); + myHandButtons.setEnableButtons(false); + opponentHandButtons.setEnableButtons(false); + if (isLoseA) { JOptionPane.showMessageDialog(null, "Botが勝利しました。"); - } else if (abstractGameState.isBLose()) { + } else { JOptionPane.showMessageDialog(null, "あなたが勝利しました。"); } - } }