Java share soure code game TicTacToe - Minimax algorithm -Java swing
After learning the MiniMax algorithm in Computer science class, I decided to practice it on Tic Tac Toe. The algorithm is simple to understand but too implement to this game it not too easy.. for me, it took me much more time than I expected.
Big thanks to this blog ,it help me alot , and i make this game on java swing base on that code !
So, I would like to share what I have learned here.Take a look..
Demo :
Big thanks to this blog ,it help me alot , and i make this game on java swing base on that code !
So, I would like to share what I have learned here.Take a look..
Demo :
Here is source of that game :
<!-----------------------------------------------------------!-->
public class Turn { enum NextMove { O, X, E } NextMove next; }
<!----------------------------------------------------------!-->
class Point{ int x, y; public Point(int x, int y) { this.x = x; this.y = y; } @Override public String toString() { return "(" + x + ", " + y + ")"; } }
<!---------------------------------------------------------!-->
class PointsAndScores{ int score; Point point; PointsAndScores(int score, Point point) { this.score = score; this.point = point; }
<!-----------------------------------------------------------------------------------!-->
class BoardGame { static int check = 0 ; List<Point> availablePoints; int[][] boardGame = new int[3][3]; public BoardGame() { } public boolean isGameOver() { return (isXWon() || isOWon() || getAvailableStates().isEmpty()); } public boolean isXWon() { if ((boardGame[0][0] == boardGame[1][1] && boardGame[0][0] == boardGame[2][2] && boardGame[0][0] == 1) || (boardGame[0][2] == boardGame[1][1] && boardGame[0][2] == boardGame[2][0] && boardGame[0][2] == 1)) { //x win return true; } for (int i = 0; i < 3; ++i) { if (((boardGame[i][0] == boardGame[i][1] && boardGame[i][0] == boardGame[i][2] && boardGame[i][0] == 1) || (boardGame[0][i] == boardGame[1][i] && boardGame[0][i] == boardGame[2][i] && boardGame[0][i] == 1))) { // x win return true; } } return false; } public boolean isOWon() { if ((boardGame[0][0] == boardGame[1][1] && boardGame[0][0] == boardGame[2][2] && boardGame[0][0] == 2) || (boardGame[0][2] == boardGame[1][1] && boardGame[0][2] == boardGame[2][0] && boardGame[0][2] == 2)) { //o win return true; } for (int i = 0; i < 3; ++i) { if ((boardGame[i][0] == boardGame[i][1] && boardGame[i][0] == boardGame[i][2] && boardGame[i][0] == 2) || (boardGame[0][i] == boardGame[1][i] && boardGame[0][i] == boardGame[2][i] && boardGame[0][i] == 2)) { // o win return true; } } return false; } public List<Point> getAvailableStates() { availablePoints = new ArrayList<>(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (boardGame[i][j] == 0) { // trang thai do dang rong availablePoints.add(new Point(i, j)); } } } // for(int i = 0 ; i < availablePoints.size() ; i++) // { // System.out.println(availablePoints.get(i).toString()+"\n"); // } return availablePoints; } public void placeAMove(Point point, int player) { boardGame[point.x][point.y] = player; //player = 1 for X, 2 for O } public void displayBoard() { System.out.println(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { System.out.print(boardGame[i][j] + " "); } System.out.println(); } } Point computersMove; public int minimax(int depth, int turn) { if (isXWon()) return +1; //X won if (isOWon()) return -1; // O won List<Point> pointsAvailable = getAvailableStates(); if (pointsAvailable.isEmpty()) return 0; //draw int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i = 0; i < pointsAvailable.size(); ++i) { Point point = pointsAvailable.get(i); if (turn == 1) { // human , X // System.out.println("turn =1"); placeAMove(point, 1); int currentScore = minimax(depth + 1, 2); max = Math.max(currentScore, max); if(depth == 0)System.out.println("position ("+pointsAvailable.get(i).x+", "+pointsAvailable.get(i).y+") = "+currentScore); if(currentScore >= 0){ if(depth == 0) computersMove = point;} if(currentScore == 1){boardGame[point.x][point.y] = 0; break;} if(i == pointsAvailable.size()-1 && max < 0){if(depth == 0) computersMove = point;} // System.out.println("MAX = "+max); } else if (turn == 2) { // computer , 2 // System.out.println("turn =2"); placeAMove(point, 2); int currentScore = minimax(depth + 1, 1); min = Math.min(currentScore, min); if(min == -1){boardGame[point.x][point.y] = 0; break;} // System.out.println("Min = "+min); } boardGame[point.x][point.y] = 0; //Reset this point } // System.out.println("return : "+ (turn == 1?max:min)); return turn == 1?max:min; } //Functions for GUI public int returnNextMove() { if (isGameOver()) return -1; minimax(0, 1); return computersMove.x * 3 + computersMove.y; } public void resetBoard(){ for(int i = 0;i<3;++i) for(int j=0;j<3;++j) boardGame[i][j] = 0; } }
//Class GUI - MAIN
public class TicTacToe_GUI extends JFrame implements ActionListener, MouseListener{ JPanel pGame; JPanel pControl; JPanel plogo; JButton btplay, exit; JRadioButtonMenuItem human , computer; int WHO_FIRST = 0; BoardGame boardGame = new BoardGame(); Turn turn = new Turn(); GridLayout grid = new GridLayout(3, 3); JButton bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9; JButton button[]; ImageIcon iX = new ImageIcon("image/x.png"); ImageIcon iO = new ImageIcon("image/o.jpg"); public TicTacToe_GUI() { setTitle("Nguyen Van Thanh() - DEMO TICTACTOE - ThanhCS94"); setLayout(new BorderLayout()); setBackground(Color.WHITE); pGame = new JPanel(); pGame.setBackground(Color.WHITE); pGame.setLayout(grid); plogo = new JPanel(); add(pGame, BorderLayout.CENTER); add(plogo, BorderLayout.NORTH); plogo.add(new JLabel(new ImageIcon("logo.jpg"))); pControl = new JPanel(); pControl.setLayout(new GridLayout(4, 1)); JPanel whofirst = new JPanel(); whofirst.add(human = new JRadioButtonMenuItem ("I'm first")); human.setBackground(Color.WHITE); whofirst.add(computer = new JRadioButtonMenuItem ("You first")); computer.setBackground(Color.WHITE); ButtonGroup a = new ButtonGroup(); a.add(human); a.add(computer); human.setSelected(true); pGame.setVisible(false); pControl.add(whofirst); pControl.setBackground(Color.WHITE); whofirst.setBackground(Color.WHITE); pControl.add(btplay = new JButton()); pControl.add(exit = new JButton()); btplay.setIcon(new ImageIcon("play.png")); exit.setIcon(new ImageIcon("ecit.jpg")); btplay.setOpaque(false); btplay.setContentAreaFilled(false); btplay.setBorderPainted(false); exit.setOpaque(false); exit.setContentAreaFilled(false); exit.setBorderPainted(false); btplay.addActionListener(this); exit.addActionListener(this); add(pControl, BorderLayout.EAST); setButton(); for(final JButton bt : button) { bt.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(bt.getName().equalsIgnoreCase("")) { int indext = -1; for(int i = 0 ; i < button.length ; i++) { if(bt == button[i]) { indext =i; System.out.println("position : "+indext); button[i].setIcon(new ImageIcon("image/x.png")); } } boardGame.placeAMove(new Point(indext/3, indext%3), 2); boardGame.displayBoard(); System.out.println("Placed a move at: (" + indext/ 3 + ", " + indext % 3 + ")"); boolean mark = true; int next = boardGame.returnNextMove(); if (next != -1) { //If the game isn't finished yet! int indexCell = next; button[indexCell].setIcon(new ImageIcon("image/o.jpg")); button[indexCell].setName("1");//used // button[indexCell].setUserData(mark); //Used! // System.out.println("Computer has evaluated the next move! " + indexCell); boardGame.placeAMove(new Point(indexCell / 3, indexCell % 3), 1); bt.setName("1"); } if (boardGame.isGameOver()) { if (boardGame.isXWon()) { JOptionPane.showMessageDialog(null, "You lost"); boardGame.resetBoard(); boardGame.displayBoard(); setVisible(false); new TicTacToe_GUI(); } else { JOptionPane.showMessageDialog(null, "Draw"); boardGame.resetBoard(); boardGame.displayBoard(); setVisible(false); new TicTacToe_GUI(); } } } } }); } int x=this.getToolkit().getScreenSize().width/2-200; int y=this.getToolkit().getScreenSize().height/2-200; setLocation(x,y); setSize(400, 450); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } private void setButton() { bt1 = new JButton(); bt1.setName(""); bt2 = new JButton();bt2.setName(""); bt3 = new JButton();bt3.setName(""); bt4 = new JButton();bt4.setName(""); bt5 = new JButton();bt5.setName(""); bt6 = new JButton();bt6.setName(""); bt7 = new JButton();bt7.setName(""); bt8 = new JButton();bt8.setName(""); bt9 = new JButton();bt9.setName(""); button= new JButton[9]; JButton bt[] = {bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9}; for(int i = 0 ; i < button.length ;i++) { button[i] = bt[i]; button[i].setBackground(Color.WHITE); pGame.add(button[i]); } } public static void main(String[] args) { new TicTacToe_GUI(); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void actionPerformed(ActionEvent e) { if(e.getSource()==btplay) { WHO_FIRST = getFirst(); if(WHO_FIRST==1)//danh truoc { turn.next = Turn.NextMove.O; pControl.setVisible(false); pGame.setVisible(true); } if(WHO_FIRST==2)//computer { pControl.setVisible(false); pGame.setVisible(true); int index = new Random().nextInt(9); button[index].setIcon(new ImageIcon("image/o.jpg")); button[index].setName("1"); boardGame.placeAMove(new Point(index / 3, index % 3), 1); turn.next = Turn.NextMove.X; } } if(e.getSource()==exit) { System.exit(0); } } private int getFirst() { if(human.isSelected()) return 1; else if(computer.isSelected()) return 2; return 0; } }
Thanks
ReplyDelete