Giới thiệu

Tic Tac Toe là một trò chơi khá phổ biến dùng viết trên bàn cờ giấy có 9 ô. Hai người chơi, một người dùng ký hiệu O, người kia dùng ký hiệu X, lần lượt điền ký hiệu của mình vào các ô. Người thắng cuộc là người đầu tiên tạo được một dãy 3 ký hiệu của mình theo các chiều ngang, dọc hay chéo đều được. Nếu sau khi đã lấp đầy các ô trống mà vẫn không có ai đạt được một dãy 3 ô thẳng hàng thì sẽ là hòa. Hình sau mô tả 3 trường hợp ví dụ:

*
*
*

Lớp TicTacToe chứa 9 ô

whoseTurn: Chỉ ra lượt chơi của người chơi, ban đầu là X. – cell: Một mảng 2 chiều 3 x 3 các ô. – jlblStatus: Một nhãn (label) để hiển thị trạng thái của game. – TicTacToe(): Khởi tạo giao diện người dùng. – isFull(): Trả về giá trị true nếu tất cả các ô đều đã được đánh. – isWon(token: char): Trả về giá trị true nếu người chơi có ký hiệu token đã thắng.

Với lí do là lớp Cell chỉ được dùng trong lớp TicTacToe nên nó có thể được định nghĩa bên trong lớp TicTacToe (inner class). Chi tiết của chương trình được thể hiện bên dưới:

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

public class TicTacToe extends JApplet { // Chỉ ra lượt chơi của người chơi, giá trị ban đầu là X private char whoseTurn = ‘X’;

// Khởi tạo các ô private Cell cells = new Cell;

// Khởi tạo label trạng thái của trò chơi private JLabel jlblStatus = new JLabel(“X’s turn to play”);

/** Initialize UI */ public TicTacToe() { // Panel p chứa các ô JPanel p = new JPanel(new GridLayout(3, 3, 0, 0)); for (int i = 0; i for (int j = 0; j p.add(cells = new Cell());

// Thay đổi đường viền của các ô và label trạng thái p.setBorder(new LineBorder(Color.red, 1)); jlblStatus.setBorder(new LineBorder(Color.yellow, 1));

// Đưa panel và label vào trong applet add(p, BorderLayout.CENTER); add(jlblStatus, BorderLayout.SOUTH); }

/** Xác định xem liệu tất cả các ô đều đã được đánh hay chưa */ public boolean isFull() { for (int i = 0; i for (int j = 0; j if (cells.getToken() == ‘ ‘) return false;

return true; }

/** Xác định xem liệu người chơi với ký hiện token đã thắng hay chưa */ public boolean isWon(char token) { for (int i = 0; i if ((cells.getToken() == token) && (cells.getToken() == token) && (cells.getToken() == token)) { return true; }

for (int j = 0; j if ((cells.getToken() == token) && (cells.getToken() == token) && (cells.getToken() == token)) { return true; }

if ((cells.getToken() == token) && (cells.getToken() == token) && (cells.getToken() == token)) { return true; }

if ((cells.getToken() == token) && (cells.getToken() == token) && (cells.getToken() == token)) { return true; }

return false; }

// Một inner class đại diện cho một ô public class Cell extends JPanel { // Ký hiệu của ô này private char token = ‘ ‘;

public Cell() { setBorder(new LineBorder(Color.black, 1)); // Thay đổi đường viền của ô addMouseListener(new MyMouseListener()); // Đăng ký listener }

/** Trả về ký hiệu của ô */ public char getToken() { return token; }

/** Nhập một ký hiệu mới cho ô */ public void setToken(char c) { token = c; repaint(); }

/** Vẽ ô */ protected void paintComponent(Graphics g) { super.paintComponent(g);

if (token == ‘X’) { g.drawLine(10, 10, getWidth() – 10, getHeight() – 10); g.drawLine(getWidth() – 10, 10, 10, getHeight() – 10); } else if (token == ‘O’) { g.drawOval(10, 10, getWidth() – 20, getHeight() – 20); } }

private class MyMouseListener extends MouseAdapter { /** Xử lý sự kiện nhấn chuột trong một ô */ public void mouseClicked(MouseEvent e) { // Nếu một ô còn trống và trò chơi vẫn chưa kết thúc if (token == ‘ ‘ && whoseTurn != ‘ ‘) { setToken(whoseTurn); // Thay đổi ký hiệu cho ô

// Kiểm tra trạng thái của trò chơi if (isWon(whoseTurn)) { jlblStatus.setText(whoseTurn + ” won! The game is over”); whoseTurn = ‘ ‘; // Trò chơi kết thúc } else if (isFull()) { jlblStatus.setText(“Draw! The game is over”); whoseTurn = ‘ ‘; // Trò chơi kết thúc } else { // Thay đổi lượt chơi whoseTurn = (whoseTurn == ‘X’) ? ‘O’: ‘X’; // Hiển thị lượt chơi jlblStatus.setText(whoseTurn + “’s turn”); } } } } }

/** Phương thức main() cho phép applet này chạy như là một ứng dụng */ public static void main(String args) { // Tạo một frame JFrame frame = new JFrame(“TicTacToe”);

// Tạo một thể hiện của applet TicTacToe applet = new TicTacToe();

// Thêm thể hiện của applet vào trong frame frame.add(applet, BorderLayout.CENTER);

// Hiển thị frame frame.setSize(300, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }

Kết luậnLớp TicTacToe khởi tạo giao diện người dùng với 9 ô đặt trong một panel với GridLayout. Một label có tên là jlblStatus được sử dụng để hiển thị trạng thái của trò chơi. Biến whoeTurn được sử dụng để lưu ký hiệu tiếp theo sẽ được gán cho các ô.

Bạn đang xem: Tic tac toe là gì

Xem thêm: Trợ Giảng Tiếng Anh Là Gì, Vai Trò Của Trợ Giảng

Xem thêm: Laser Là Gì – Vai Trò Của Laser Trong Y Học Phần 2

Phương thức isFull() và isWon() được sử dụng để kiểm tra trạng thái của trò chơi.

Bởi vì lớp Cell là inner class của lớp TicTacToe nên biến whoseTurn và các phương thức isFull() isWon() của lớp TicTacToe đều có thể sử dụng được trong lớp Cell. Inner class giúp cho chương trình trở nên đơn giản và ngắn gọn hơn. Nếu lớp Cell không được khai báo là inner class của lớp TicTacToe thì chúng ta cần phải truyền một đối tượng của TicTacToe vào trong lớp Cell để lớp này có thể sử dụng được các biến và phương thức của lớp TicTacToe. Bạn có thể thử viết lại chương trình này mà không sử dụng inner class. Sự kiện MouseEvent được đăng ký cho từng ô, nếu một ô trống được nhấn chuột trong khi trò chơi vẫn chưa kết thúc thì ký hiệu hiện tại sẽ được đặt cho ô đó. Nếu trò chơi kết thúc, biến whoseTurn sẽ được gán giá trị ‘ ‘, còn nếu không thì whoseTurn sẽ chuyển sang giá trị của lượt chơi mới.

Mẹo:

Hãy sử dụng phương pháp tiếp cận tăng cường (incremental approach) trong việc phát triển và kiểm thử một dự án Java thuộc loại này. Chương trình ở trên có thể được chia thành 5 bước như sau:

Dựng giao diện người dùng và hiển thị ký hiệu X trong một ô cố định. Tạo cho các ô khả năng hiển thị ký hiệu X mỗi khi một ô nào đó được nhấn chuột. Kết hợp giữa hai người chơi sao cho các ký hiệu XO được hiển thị thay phiên nhau. Kiểm tra xem một người chơi đã thắng hay chưa, hoặc là tất cả các ô đều đã được đánh. Hiển thị thông báo trên label trạng thái sau mỗi nước đi của người chơi.

Chuyên mục: Hỏi Đáp