import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.LineBorder;
public class TicTacToe extends JFrame{
//声明char变量 whoseTurn,并赋初值X;
private char whoseTurn='X';
//创建并初始化一个3*3的Cell类对象二维数组
private Cell[][] cells=new Cell[3][3];
//创建一个并初始化一个标签 用来显示游戏状态
private JLabel jlbMessage=new JLabel("现在轮到X方下棋了");
//创建并初始化一个按钮,用来进行新游戏
private JButton jbtNewGame=new JButton("新游戏");
//创建UI
public TicTacToe(){
//创建一个面板来设置单元格
JPanel p1=new JPanel();
//创建一个面板来装 jbtNewGame
JPanel p2=new JPanel();
p1.setLayout(new GridLayout(3,3,0,0));
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
p1.add(cells[i][j]=new Cell());
}
}
//为单元格设置边框
p1.setBorder(new LineBorder(Color.red,1));//创建具有指定颜色和厚度的边框
jlbMessage.setBorder(new LineBorder(Color.yellow,1));
//设置p2里的属性
p2.setLayout(new FlowLayout());
p2.add(jbtNewGame);
//放置p和jlbMessage
add(p1,BorderLayout.CENTER);
add(jlbMessage,BorderLayout.SOUTH);
add(p2,BorderLayout.NORTH);
}
//判断单元格是否填满
public boolean isFull(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(cells[i][j].getToken()==' '){
return false;
}
}
}
return true;
}
//决定究竟谁持有的token赢
public boolean isWon(char token){
//判断列是否有三个相同token的情况
for(int i=0;i<3;i++){
if((cells[i][0].getToken())==token&&(cells[i][1].getToken()==token)&&(cells[i][2].getToken()==token)){
return true;
}
}
//判断行是否有三个相同token的情况
for(int j=0;j<3;j++){
if((cells[0][j].getToken()==token)&&(cells[1][j].getToken()==token)&&(cells[2][j].getToken()==token)){
return true;
}
}
//判断主对角线是否有三个相同token的情况
if((cells[0][0].getToken()==token)&&(cells[1][1].getToken()==token)&&(cells[2][2].getToken()==token)){
return true;
}
//判断副对角线是否有三个相同token的情况
if((cells[0][2].getToken()==token)&&(cells[1][1].getToken()==token)&&(cells[2][0].getToken()==token)){
return true;
}
//其余的情况 为平局 返回false
return false;
}
//cell类
public class Cell extends JPanel{
//单元格标记,默认为' '(空)
private char token=' ';
//构造方法
public Cell(){
//为单元格画边框(边框色为黑,且厚度为1)
setBorder(new LineBorder(Color.black,1));
//注册鼠标监听器
addMouseListener(new MouseListener());
//注册按钮监听器
jbtNewGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(e.getSource()==jbtNewGame){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cells[i][j].setToken(' ');
cells[i][j].repaint();
}
}
jlbMessage.setText("开始新游戏,X先手");
whoseTurn='X';
}
}
});
}
//返回token
public char getToken(){
return token;
}
//设置一个新的token
public void setToken(char c){
token=c;
repaint();//刷新
}
//覆盖paintComponent方法
protected void paintComponent(Graphics g){
super.paintComponent(g);
//若token为X,则画相交直线
if(token=='X'){
g.drawLine(10,10,getWidth()-10,getHeight()-10);
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}
//若token为O,则画椭圆
else if(token=='O'){
g.drawOval(10,10,getWidth()-20,getHeight()-20);
}
}
//用监听器接口适配器来实现注册鼠标监听器
private class MouseListener extends MouseAdapter{
//处理鼠标在单元格上的点击事件
public void mouseClicked(MouseEvent e){
//若单元格为空并且游戏未结束
if(token==' '&&whoseTurn!=' '){
setToken(whoseTurn);
//检查游戏状态
if(isWon(whoseTurn)){
jlbMessage.setText(whoseTurn+"赢得了比赛");
whoseTurn=' ';
}
else if(isFull()){
jlbMessage.setText("平局,游戏结束");
whoseTurn=' ';
}
else{
whoseTurn=(whoseTurn=='X')?'O':'X';
jlbMessage.setText("现在轮到"+whoseTurn+"下了");
}
}
}
}
}
//主类
public static void main(String[] args){
TicTacToe frame=new TicTacToe();
frame.setSize(400,400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}