Skip to content

Instantly share code, notes, and snippets.

@ngobach
Last active October 3, 2023 21:09
Show Gist options
  • Save ngobach/bb39fbda62c5d6a0ffc127c732d2d9c6 to your computer and use it in GitHub Desktop.
Save ngobach/bb39fbda62c5d6a0ffc127c732d2d9c6 to your computer and use it in GitHub Desktop.
JAV++
/**
*
* Bai Tap co caro
*
* @SinhVien Ngo Xuan Bach
* @MaSinhVien 1381310007
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* Ham chinh cua chuong trinh
* Nhap vao kich thuoc mong muon va xay dung cua so game
*
* @author thanbaiks
*/
public class Bach_NgoXuan {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
// Bien luu kich thuoc ban co
int size = -1;
while (true) {
String result = JOptionPane.showInputDialog("Nhap kich thuoc ban co\nMin: 5, Max: 20", "18");
if (result != null)
try {
size = Integer.parseInt(result);
if (size < 5 || size > 20) {
JOptionPane.showMessageDialog(null, "Toi thieu 5 va toi da 20. Vui long nhap lai");
} else break;
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Ban nhap sai dinh dang. Vui long nhap lai");
}
else System.exit(0);
}
GameWindow game = GameWindow.create(size);
if (game == null) {
// That bai
System.out.println("Khong the bat dau game. Moi truong CLI");
System.exit(-1);
} else {
// Thanh cong
game.setVisible(true);
}
}
}
/**
* Lop Nguoi choi
*
* @author thanbaiks
*/
class Player {
/**
* Ten nguoi choi
*/
private String name;
/**
* Ki tu nguoi choi
*/
private char c;
private int score;
private JLabel label;
/**
* Ham khoi tao nguoi choi
*
* @param name Ten cua nguoi choi se duoc hien thi
* @param c Ki tu cua nguoi choi nay ('X' hay 'O')
*/
public Player(String name, char c) {
this.name = name;
this.c = c;
score = 0;
label = new JLabel(name, SwingConstants.CENTER);
label.setFont(new Font("SansSerif", Font.BOLD, 32));
label.setPreferredSize(new Dimension(0, 100));
}
/**
* Lay ten nguoi choi
* @return Ten nguoi choi
*/
public String getName() {
return name;
}
/**
* Lay ki tu choi cua nguoi choi
*
* @return Ki tu choi
*/
public char getChar() {
return c;
}
/**
* Tra ve diem so cua nguoi choi
* So lan thang
*
* @return diem so
*/
private int getScore() {
return score;
}
/**
* Tra ve label gan voi nguoi choi nay
*
* @return
*/
public JComponent getUI () {
return label;
}
/**
* Ham tang diem cua nguoi choi khi chien than
* Dat lai gia tri cho label
*/
public void won() {
score++;
label.setText(name + " - " + score);
}
/**
* Su kien khi nguoi choi co luot
* Thay doi vien cua label
*/
public void gotTurn() {
label.setBorder(BorderFactory.createLineBorder(Color.red, 5));
}
/**
* SU kien khi nguoi choi mat luot
* Thay doi vien cua label
*/
public void lostTurn() {
label.setBorder(null);
}
}
/**
* Lop Ke thua JButton
* @author thanbaiks
*/
class GameButton extends JButton {
/**
* Nguoi choi cua Button nay
*/
private Player p;
/**
* Chi so hang va cot cua button tren ban co
*/
private int x,y;
/**
* Ham khoi tao
* @param listener lang nghe su kien click
* @param x toa do x
* @param y toa do y
*/
public GameButton(ActionListener listener, int x, int y) {
super();
this.x = x;
this.y = y;
setSize(100,100);
setFont(new Font(Font.DIALOG, Font.BOLD, 12));
setPreferredSize(new Dimension(42, 42));
addActionListener(listener);
}
/**
* Thuc hien thao tac tren o co nay
*
* @param p Nguoi choi thuc hien
*/
public void play(Player p) {
this.p = p;
setText(String.valueOf(p.getChar()));
if (p.getChar() == 'O')
setForeground(Color.red);
else
setForeground(Color.BLACK);
}
/**
* Kiem tra xem Button nay da co nguoi danh vao chua
* @return boolean
*/
public boolean isPlayable() {
return p == null;
}
/**
* Dua o co ve trang thai ban dau
* Trang thai trong de co the choi van moi
*/
public void reset() {
setText("");
setForeground(Color.black);
p = null;
}
/**
* Lay toa do X cua Button (ô cờ)
*
* @return toa do X
*/
public int getPosX() {
return x;
}
/**
* Lay toa do Y cua Button (ô cờ)
*
* @return toa do Y
*/
public int getPosY() {
return y;
}
/**
* Tra ve nguoi choi thuc hien thao tac o o co nay
* return player hoac null neu o co trong
*/
public Player getPlayer() {
return p;
}
}
/**
* Lop ban co
* @author thanbaiks
*/
class GameWindow extends JFrame {
/**
* Game logic
* Ho tro viec tinh toan so o lien tuc dua vao de quy
*/
private static final int[][] DIRECTIONS = {{0,1},{1,1},{1,0},{-1,1}};
/**
* Bien luu kich thuoc cua ban co
*/
private final int size;
/**
* Hai nguoi choi game caro
*/
private final Player player1 = new Player("Batman", 'X');
private final Player player2 = new Player("Superman", 'O');
/**
* Bien luu nguoi choi hien tai
*/
private Player mCurrentPlayer = null;
/**
* Ma tran button (ô cờ)
*/
private GameButton[][] buttons;
/**
* Bien dem so o con trong
* De kiem tra trang thai van dau co hoa hay khong
*/
private int countEmpty;
/**
* Ham khoi tao GameWindow
*
* @param size Kich thuoc ban co
* @throws HeadlessException Khi moi truong nay khong kha dung (Headless)
*/
private GameWindow(int size) throws HeadlessException {
super("Game Window - Ngo Xuan Bach (1381310007)");
this.size = size;
}
/**
* Factory pattern
* Tao 1 instance cua GameWindow
* Hoac tra ve null neu that bai
*
* @param size kich thuoc ban co
* @return GameWindow obj neu thanh cong hoac null neu day la moi truong headless (CLI)
*/
public static GameWindow create(int size){
try {
GameWindow game = new GameWindow(size);
game.init();
return game;
} catch (HeadlessException e) {
return null;
}
}
/**
* Ham xay dung ban co
*/
private void init() {
JPanel gamePanel = new JPanel();
gamePanel.setLayout(new GridLayout(size,size));
// Xay dung lop lang nghe su kien click vao buttons
// Callback: onPlayerPlayed
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
GameButton btn = (GameButton)e.getSource();
if (btn.isPlayable()){
btn.play(currentPlayer());
if (!onPlayerPlayed(currentPlayer() ,btn.getPosX(), btn.getPosY())) {
// Khong chien thang
// Kiem tra hoa
countEmpty--;
if (countEmpty <= 0) {
// DRAW!
gameEnded(null);
}else {
// Luot choi ke tiep
nextPlayer();
}
}
} else {
Toolkit.getDefaultToolkit().beep();
}
}
};
// Xay dung ma tran o co
buttons = new GameButton[size][size];
for (int i=0; i<size; i++) {
for (int j=0;j<size;j++){
buttons[i][j] = new GameButton(listener, i, j);
gamePanel.add(buttons[i][j]);
}
}
// Bang diem va thong tin nguoi choi
JButton resignButton = new JButton("Bỏ cuộc");
resignButton.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
nextPlayer().won();
gameEnded(currentPlayer());
}
});
resignButton.setFont(new Font("SansSerif", Font.BOLD, 32));
resignButton.setForeground(Color.BLUE);
JPanel scoreBoard = new JPanel(new GridLayout(1, 3));
scoreBoard.add(player1.getUI());
scoreBoard.add(resignButton);
scoreBoard.add(player2.getUI());
// Day components vao form
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
container.add(gamePanel, BorderLayout.CENTER);
container.add(scoreBoard, BorderLayout.SOUTH);
getContentPane().add(container);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
// Khoi tao menubar
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem menuItem;
menuItem = new JMenuItem("Luật chơi");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(GameWindow.this,
"Mỗi người chơi đánh lần lượt, trong mỗi lượt được đánh vào 1 ô\n" +
"Người chơi nào đạt được 5 ô liên tục trước sẽ chiến thắng\n" +
"Sau khi đánh hết các ô mà không có người chiến thắng sẽ HÒA",
"Luật chơi",
JOptionPane.INFORMATION_MESSAGE
);
}
});
menu.add(menuItem);
menuItem = new JMenuItem("Giới thiệu");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(GameWindow.this,
"Game cờ caro\n" +
"Giao diện JavaSwing, System native LookAndFeel\n"+
"Tác giả: Ngô Xuân Bách - Mã số SV: 1381310007",
"Giới thiệu",
JOptionPane.INFORMATION_MESSAGE
);
}
});
menu.add(menuItem);
menu.add(new JSeparator());
menuItem = new JMenuItem("Thoát");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (JOptionPane.showConfirmDialog(GameWindow.this, "Thoát khỏi trò chơi?","Xác nhận", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
menu.add(menuItem);
menubar.add(menu);
setJMenuBar(menubar);
// Bat dau game moi
newGame();
}
/**
* Dua game ve trang thai ban dau
* Bat dau mot game moi
*/
private void newGame() {
for (GameButton[] gbs : buttons)
for (GameButton gb : gbs)
gb.reset();
countEmpty = size*size;
mCurrentPlayer = player1;
notifyTurnChanged();
}
/**
* Ham chuyen nguoi choi
* @return tra ve nguoi choi tiep theo
*/
private Player nextPlayer() {
mCurrentPlayer = mCurrentPlayer == player1 ? player2 : player1;
notifyTurnChanged();
return mCurrentPlayer;
}
/**
* Ham tra ve nguoi choi hien tai
* @return
*/
private Player currentPlayer() {
return mCurrentPlayer;
}
/**
* Xu ly su kien nguoi choi thuc hien mot luot choi
*
* @param player Nguoi choi thuc hien luot di
* @param x Chi so hang cua luot di
* @param y Chi so cot cua luot di
* @return true neu nguoi choi chien thang
*/
private boolean onPlayerPlayed(Player player, int x, int y) {
int i = 0;
for (int[] dir : DIRECTIONS) {
i = Math.max(calc(x, y, player, dir[0], dir[1]) + calc(x, y, player, -dir[0], -dir[1]) - 1, i);
}
if (i >= 5) {
player.won();
gameEnded(player);
return true;
}
return false;
}
/**
* Tinh toan so o co lien tuc cua nguoi choi
* Dua vao thuat toan de quy
*/
private int calc(int x, int y, Player who, int ax, int ay) {
if (x < 0 || y < 0 || x >= size || y >= size || buttons[x][y].getPlayer() != who) return 0; // Nope.
else return 1 + calc(x+ax, y+ay, who, ax, ay);
}
/**
* Su kien doi luot choi
* Thay doi duong vien cua JLabel nguoi choi
*/
private void notifyTurnChanged() {
Player now = currentPlayer();
Player next = now == player1 ? player2 : player1;
next.lostTurn();
now.gotTurn();
}
/**
* Ket thuc game. Thong bao trang thai van dau
*
* @param player nguoi choi chien thang, hoac null neu hoa
*/
private void gameEnded(Player player) {
String message = player == null? "Hoa!" : player.getName() + " chien thang!";
JOptionPane.showMessageDialog(this, message, "Thong bao", JOptionPane.INFORMATION_MESSAGE);
newGame();
}
}
@Linhchuot12
Copy link

Uploading IMG_0096.png…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment