如何简化我的Java方法或将其更改为DRY

时间:2016-09-19 19:12:37

标签: java tic-tac-toe

下面的代码按预期工作,但我想简化方法,因为它目前太重复了。我希望简化代码的方法是开发一种增强AI的方法。我会让AI检查电路板上的模式并让它采取相应的行动。

public boolean checkWinner(){
        //CHECK EVERY POSSIBLE WINNING OUTCOME and return true if you find one
        //don't forget to check if the board is full (return true in that case)
            if(gameboard[0] == gameboard[1] && gameboard[1] == gameboard[2] ||
               gameboard[3] == gameboard[4] && gameboard[4] == gameboard[5] ||
               gameboard[6] == gameboard[7] && gameboard[7] == gameboard[8] ||
               gameboard[0] == gameboard[3] && gameboard[3] == gameboard[6] ||
               gameboard[1] == gameboard[4] && gameboard[4] == gameboard[7] ||
               gameboard[2] == gameboard[5] && gameboard[5] == gameboard[8] ||
               gameboard[0] == gameboard[4] && gameboard[4] == gameboard[8] ||
               gameboard[6] == gameboard[4] && gameboard[4] == gameboard[2] ){
                bigWinner();
                return true;
            }
            //loop through and look for tie
            for(int x = 0; x< gameboard.length; x++){
                if(gameboard[x] != 'O' && gameboard[x] != 'X'){
                    return false;
                }
            }
        System.out.println("Tie Game.");
        return true;
    }

TicTacToe类的完整代码如下。游戏的主类显示游戏菜单并创建一个新的TicTacToe游戏。

package pkg2baresb;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;


/**
 * This is the game logic for TicTacToe
 * @author baresb
 */
public class TicTacToe {
    //ENCAPUSLATED game variables. Super secret!
    private char[] gameboard;
    private boolean myTurn = true;
    
    /**
     * The TicTacToe's constructor
     */
    public TicTacToe(){
        //instantiate the previous declared value
        gameboard = new char[9];
        final int RADIX = 10;
        //loop through game array and start each spot with a dash
        for(int x = 0; x < gameboard.length; x++){
            gameboard[x] = Character.forDigit(x, RADIX);
         
        }
        System.out.println("TICTACTOE ONLINE.");
        
        //Loop until there's a winner
        while(!checkWinner()){
            printBoard();
            yourTurn();
        }
        printBoard();
        if(!checkWinner()) yourTurn();
        else{
            System.out.println("Game over.");
        }
    }
    
    /**
     * 
     * @return 
     */
    public boolean checkWinner(){
        //CHECK EVERY POSSIBLE WINNING OUTCOME and return true if you find one
        //don't forget to check if the board is full (return true in that case)
            if(gameboard[0] == gameboard[1] && gameboard[1] == gameboard[2] ||
               gameboard[3] == gameboard[4] && gameboard[4] == gameboard[5] ||
               gameboard[6] == gameboard[7] && gameboard[7] == gameboard[8] ||
               gameboard[0] == gameboard[3] && gameboard[3] == gameboard[6] ||
               gameboard[1] == gameboard[4] && gameboard[4] == gameboard[7] ||
               gameboard[2] == gameboard[5] && gameboard[5] == gameboard[8] ||
               gameboard[0] == gameboard[4] && gameboard[4] == gameboard[8] ||
               gameboard[6] == gameboard[4] && gameboard[4] == gameboard[2] ){
                bigWinner();
                return true;
            }
            //loop through and look for tie
            for(int x = 0; x< gameboard.length; x++){
                if(gameboard[x] != 'O' && gameboard[x] != 'X'){
                    return false;
                }
            }
        System.out.println("Tie Game.");
        return true;
    }
    
    /**
     * Use a scanner and take an input from the user
     */
    public void yourTurn(){
        //instantiate a Scanner
        Scanner s = new Scanner(System.in);
        //take an input on the position the player would like
        int selection;
        while(true){
            try{
                System.out.print("What position would you like to play: ");
                selection = s.nextInt();
                if(gameboard[selection] != 'X' && gameboard[selection] != 'O'){
                    gameboard[selection] = 'X';
                    break;
                }else{
                    System.out.println("That spot has already been taken");
                }
                
            }catch(Exception e){
                System.out.println("Invalid selection. Please try again.");
            }  
        }
        if(!checkWinner()) {
            this.myTurn = !myTurn;
            //hands things over to the computer
            computersTurn();
        }
    }
    
    /**
     * Announce who won using the myTurn boolean to remember whose turn it was
     * last
     */
    public void bigWinner(){
        if(myTurn){
            System.out.println("You won! Nice job!");
        }else{
            System.out.println("You have lost the game.");
        }
    }
    /**
     * Computer selects a random open slot and play its 'O'
     */
    public void computersTurn(){
        //OPTIONAL: MAKE THIS CODE SMARTER
        System.out.println("Now it's the computer player's turn");
        while(true){
            //generate a random number between 0 - 8
            int choice = ThreadLocalRandom.current().nextInt(0, 9);
            
            //is the space free?
            if(gameboard[choice] != 'X' && gameboard[choice] != 'O') {
                //if so, set it equal to an 'O'
                gameboard[choice] = 'O';
                //bust out of this while loop
                this.myTurn = !myTurn;
                break;
            }
            
        } //closes while loop   
    } //closes computersTurn
    
    public void printBoard(){
        for(int x = 1; x <= gameboard.length; x++){
            System.out.print(" | " + gameboard[x-1]);
            if(x % 3 == 0) System.out.println(" |");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

这对你来说可能还不够,但它总是存在的,也许如果我稍后会有一些时间我会回来让它变得更好。这就是你在那里if's的大部分。

for(int i=0; i<=6; i=i+3){
  if(gameboard[i]==gameboard[i+1] && gameboard[i+1]==gameboard[i+2])
    return true;
}
for(int i=0; i<=2;i++){
  if(gameboard[i]==gameboard[i+3] && gameboard[i+3] == gameboard[i+6])
    return true;
}
if(gameboard[0] == gameboard[4] && gameboard[4] == gameboard[8] || gameboard[6] == gameboard[4] && gameboard[4] == gameboard[2] ){
  return true;
}

答案 1 :(得分:0)

使您的代码重复性降低。您可以创建一个将游戏板和矩阵作为参数的方法:

public boolean checkWin(int[] gameBoard, int[][] winPossibilities) {

}

winPossibilities是您要检查的所有行/列/对角线。在你的情况下,它将是

final int[][] possibilities = {
    {0, 1, 2},
    {3, 4, 5},
    {6, 7, 8},
    {0, 3, 6},
    {1, 4, 7},
    {2, 5, 8},
    {0, 4, 8},
    {6, 4, 2},
};

在方法的主体中,您只需要一个简单的算法:

for (int[] indices: winPossibilities) {
    if (gameBoard[i[0]] == gameBoard[i[1]] && gameBoard[i[1]] == gameBoard[i[2]]) {
        return true;
    }
}
return false;

您可以这样调用此方法:

if(checkWin(gameboard, possibilities)){
        bigWinner();
        return true;
}
//loop through and look for tie
for(int x = 0; x< gameboard.length; x++){
    if(gameboard[x] != 'O' && gameboard[x] != 'X'){
        return false;
    }
}
System.out.println("Tie Game.");
return true;

这提供的一个好处是更灵活。如果你想改变tic tac toe的规则并决定你不能通过制作对角线来获胜,只需删除possibilities矩阵的最后两项!