简体   繁体   English

检查玩家移动在井字游戏中是否有效

[英]Checking if the player move is valid in TicTacToe game

I am making a tic tac toe game in java, between human-computer.我正在人机之间用 Java 制作井字游戏。 I need a Check to ensure that the player has made a valid move, eg that the player is not trying to make a move in a square that is already occupied.我需要一个检查来确保玩家已经做出了有效的移动,例如玩家没有试图在已经被占据的方格中移动。

I tried to write a method and call it from the chick() method, or to make if statment within win() but It didn't work.我尝试编写一个方法并从chick() 方法中调用它,或者在win() 中进行if 语句,但它不起作用。

import javax.swing.*;              
import java.awt.event.*;           
import java.awt.*;


public class XOGAMEMAIN extends JFrame implements ActionListener { 

 private JButton [][]buttons = new JButton[3][3];  
 private JButton XButton = new JButton("play with X "); 
 private JButton OButton = new JButton("play with O"); 
 private JButton CButton = new JButton("let computer start with X"); 
 private JButton C1Button = new JButton("let computer start with O");        
 private JLabel statusLabel = new JLabel(" "); 
 private XOGAMEAI game = null;

 private int human = 0; 
 private int computer = 0;  
 private boolean isPlay = false;
 private String []chars=new String[]{"","X","O"};

 private void setStatus(String s) {
  statusLabel.setText(s);
 }

 private void setButtonsEnabled(boolean enabled) {
  for(int i=0;i<3;i++)
   for(int j=0;j<3;j++) {
    buttons[i][j].setEnabled(enabled);
    if(enabled) buttons[i][j].setText(".");
   }
 }

 public XOGAMEMAIN() {

  setTitle(" X/O Game ");
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setResizable(false);

  JPanel centerPanel = new JPanel(new GridLayout(3,3));
  Font font = new Font("Arial",Font.BOLD, 32);
  for(int i=0;i<3;i++)
   for(int j=0;j<3;j++) {
    buttons[i][j] = new JButton(".");
    buttons[i][j].setFont(font);
    buttons[i][j].addActionListener(this);
    buttons[i][j].setFocusable(false);
    centerPanel.add(buttons[i][j]);
   }

  XButton.addActionListener(this);
  OButton.addActionListener(this);
  CButton.addActionListener(this);
  C1Button.addActionListener(this);

  JPanel northPanel = new JPanel();
  northPanel.add(statusLabel);

  JPanel southPanel = new JPanel();
  southPanel.add(XButton);
  southPanel.add(OButton);
  southPanel.add(CButton);  
  southPanel.add(C1Button); 
  setStatus("wlc,to start chose X or O or let computer decide");
  setButtonsEnabled(false);

  add(northPanel,"North");
  add(centerPanel,"Center");
  add(southPanel,"South");

  setSize(600,600);


  setLocationRelativeTo(null);
 }

 public static void main(String []args) {

  new XOGAMEMAIN().setVisible(true);
 }


 private void computerTurn1() {  ////////// this method for computer ( when the human chose the computer buttons to start first ) with X or O

   int []pos = game.nextMove(computer);
   if(pos!=null) {
   int i = pos[0];
   int j = pos[1];
   buttons[i][j].setText(chars[computer]);
   game.setBoardValue(i,j,computer);
   setStatus("computer did its move ");

  }

  checkState();
 }
  private void computerTurn() {  // this method for computer movment( when the human chose (X,O)buttons to start ) human method==>(using click method) and after that(computer turn==> this method will run 
   int []pos = game.nextMove(computer);
   if(pos!=null) {
   int i = pos[0];
   int j = pos[1];
   buttons[i][j].setText(chars[computer]);
   game.setBoardValue(i,j,computer);
   setStatus("computer did its move , now your turn ");

  }

  checkState();
 }

 private void gameOver(String s) {
  setStatus(s);
  setButtonsEnabled(false);
  isPlay = false;
 }


 private void checkState() {
  if(game.isWin(human)) {
   gameOver(" You've Won!");
  }
  if(game.isWin(computer)) {
   gameOver("Sorry, You Lose!");
  }
  if(game.nextMove(human)==null && game.nextMove(computer)==null) {
   gameOver(" Draw ");
  }
 }

 private void click(int i,int j) { //// this method is for human , when he click any button 

  if(game.getBoardValue(i,j)==XOGAMEAI.EMPTY) {
   buttons[i][j].setText(chars[human]);
   game.setBoardValue(i,j,human);
   checkState();
   computerTurn();}


 }

 public void actionPerformed(ActionEvent event) { //// this is action event that is senseing any click from the human(every button click ==> go for a method==> this methods are declared before )  

    if(event.getSource()==C1Button) {  /// event.getsourse mean ==> the click that human make is on C1 button ? 
      play4(); /// if yes go to method play4() ==> thats mean the computer will start first with O char 
        }

    if(event.getSource()==CButton) {  /// for computer to start first with X 
      play3();
        }

    if(event.getSource()==OButton) {  ////////// human click to start first with O==>  start play1 method  
        play1();}                        
    else {                             
   for(int i=0;i<3;i++)                      //// if this is not the first click ==> thats mean this will check in turn 2 for human for example , put not the first 1 
    for(int j=0;j<3;j++)                      ////it will go for method click() directly for any of the 9 buttons choices
     if(event.getSource()==buttons[i][j])   /// 
      click(i,j);  }  

                              ////
  if(event.getSource()==XButton) { // the same here but the human has chose Xbutton to start first 
   play();
  }else {
   for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
     if(event.getSource()==buttons[i][j])
      click(i,j);
  }
 }
 private void play4() {           //// this is play4() method , its happened when Computer supposed to start first with O
  game = new XOGAMEAI();

  human = XOGAMEAI.ONE;           // human is int number=0 , now the is Matrix defined which include "","x","O" , human=o ==> char "", human=ONE ==>char X , human=TWO ==>char  O 
  computer = XOGAMEAI.TWO;      //         /// 
  setButtonsEnabled(true);                ///
  isPlay = true;
  computerTurn1(); 
                          /// 
 }  
 private void play3() {           //// for Computer to start first with X
  game = new XOGAMEAI();

  human = XOGAMEAI.TWO;           //
  computer = XOGAMEAI.ONE;      //         /// 
  setButtonsEnabled(true);                ///
  isPlay = true;
  computerTurn1(); 
                          /// 
 }  

 private void play1() {           //// for O
  game = new XOGAMEAI();

  human = XOGAMEAI.TWO;           //
  computer = XOGAMEAI.ONE;      //

  setStatus("Your Turn");         /// 
  setButtonsEnabled(true);                ///
  isPlay = true;                       /// 
 }                                  ////
 private void play() {        ////// for X 
  game = new XOGAMEAI();

  human = XOGAMEAI.ONE;
  computer = XOGAMEAI.TWO;

  setStatus("Your Turn");
  setButtonsEnabled(true);
  isPlay = true;
 }
 public static class XOGAMEAI {

 /* the board */
 private int board[][];
 /* empty */
 public static final int EMPTY = 0;
 /* player one */
 public static final int ONE = 1;
 /* player two */
    public static final int TWO = 2;

 public XOGAMEAI() {
  board = new int[3][3];
 }

 /* get the board value for position (i,j) */
 public int getBoardValue(int i,int j) {
  if(i < 0 || i >= 3) return EMPTY;
  if(j < 0 || j >= 3) return EMPTY;
  return board[i][j];
    }

 /* set the board value for position (i,j) */
 public void setBoardValue(int i,int j,int token) {////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  if(i < 0 || i >= 3) return;
  if(j < 0 || j >= 3) return;
  board[i][j] = token;
    }

 /* calculate the winning move for current token */
 public int []nextWinningMove(int token) {

  for(int i=0;i<3;i++)
   for(int j=0;j<3;j++)
    if(getBoardValue(i, j)==EMPTY) {
     board[i][j] = token;
     boolean win = isWin(token);
     board[i][j] = EMPTY;
     if(win) return new int[]{i,j};
    }

  return null;
    }

    public int inverse(int token) {
  return token==ONE ? TWO : ONE;
 }

    /* calculate the best move for current token */
    public int []nextMove(int token) {

        /* lucky position in the center of board*/
        if(getBoardValue(1, 1)==EMPTY) return new int[]{1,1};

        /* if we can move on the next turn */
        int winMove[] = nextWinningMove(token);
        if(winMove!=null) return winMove;

        /* choose the move that prevent enemy to win */
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                if(getBoardValue(i, j)==EMPTY)
                {
                    board[i][j] = token;
              boolean ok = nextWinningMove(inverse(token)) == null;
                    board[i][j] = EMPTY;
                    if(ok) return new int[]{i,j};
                }

        /* choose available move */
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                if(getBoardValue(i, j)==EMPTY)
                    return new int[]{i,j};

        /* no move is available */
        return null;
    }

 /* determine if current token is win or not win */
 public boolean isWin(int token) {
  final int DI[]={-1,0,1,1};
  final int DJ[]={1,1,1,0};
  for(int i=0;i<3;i++)
   for(int j=0;j<3;j++) {

    // we skip if the token in position(i,j) not equal current token */
    if(getBoardValue(i, j)!=token){
         continue;

    }

    for(int k=0;k<4;k++) {
     int ctr = 0;
                 while(getBoardValue(i+DI[k]*ctr, j+DJ[k]*ctr)==token) ctr++;

     if(ctr==3) return true;
    }
  }
  return false;
    }

} 

}

click(int i, int j)方法中,您检查条件if(game.getBoardValue(i,j)==XOGAMEAI.EMPTY) - 这不是您想要的吗?

OK, I've found the bug, it was in the ActionPerformed method.好的,我找到了错误,它在 ActionPerformed 方法中。 The problem was, you wrote问题是,你写道

if(xbutton pressed){...}
else{click()}
if(ybutton pressed){...}
else{click()}

And both else statements were executed.并且执行了两个else语句。 Here's the fixed code:这是固定代码:

public void actionPerformed(ActionEvent event) { //// this is action event
                                                    //// that is senseing
                                                    //// any click from the
                                                    //// human(every button
                                                    //// click ==> go for a
                                                    //// method==> this
                                                    //// methods are
                                                    //// declared before )

    if (event.getSource() == C1Button) { /// event.getsourse mean ==> the
                                            /// click that human make is on
                                            /// C1 button ?
        play4(); /// if yes go to method play4() ==> thats mean the computer
                    /// will start first with O char
    } else if (event.getSource() == CButton) { /// for computer to start
                                                /// first with
        /// X
        play3();
    }

    else if (event.getSource() == OButton) { ////////// human click to start
        ////////// first with O==> start
        ////////// play1 method
        play1();
    } else if (event.getSource() == XButton) { // the same here but the
                                                // human has
        // chose Xbutton to start first
        play();
    } else {
        for (int i = 0; i < 3; i++) //// if this is not the first click ==>
                                    //// thats mean this will check in turn
                                    //// 2 for human for example , put not
                                    //// the first 1
            for (int j = 0; j < 3; j++) //// it will go for method click()
                                        //// directly for any of the 9
                                        //// buttons choices
                if (event.getSource() == buttons[i][j]) ///
                    click(i, j);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM