井字棋java代码_JAVA 井字棋
有時候我們可以用java編寫一些小游戲,比如井字棋,這是一個很簡單的程序,如圖效果;
我們可以將它分為棋子,棋盤,框架啟動類表示;
首先我們來編寫棋子類,棋子類里有棋子的坐標和形狀的表示,
用1表示圓圈,2表示方框
public class Chess {
private int x;
private int y;//棋子的索引
private int form;//棋子的形狀,1是圓圈,2是方框
public Chess(int x,int y,int form) {//構造函數(shù)
this.x=x;
this.y=y;
this.form=form;
}
public int getX() {//get函數(shù)
return x;
}
public int getY() {
return y;
}
public int getForm() {
return form;
}
}
接下來進行框架類的編寫,創(chuàng)建一個類來繼承JFrame類,用來啟動游戲,放置面板對象,設置大小,設置標題,一個游戲少不了一些按鈕,井字棋中有三個按鈕,重新開始游戲按鈕,悔棋按鈕和退出游戲按鈕,有按鈕就有相應的事件處理,這時候我們需要一個類繼承事件處理類,并將三個按鈕和事件處理進行綁定;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/*
* 井字棋的主框架類
*
*/
public class ChessJFrame extends JFrame {
private Chessbord chessbord;//聲明一個棋盤對象
private Buttonrestartgame;//聲明一個重新開始按鈕
private Buttonbackgame;//聲明一個悔棋按鈕
private Buttonexitgame;//聲明一個退出游戲按鈕
private JPanel jp;//面板對象,存放按鈕
public ChessJFrame() {//構造函數(shù),對參數(shù)初始化
setTitle("井字棋");//設置表題名稱
MyActLister ma=new MyActLister();//事件處理對象
chessbord=new Chessbord();//棋盤對象
restartgame=new Button("重新開始");//
backgame=new Button("悔棋");
exitgame=new Button("退出");//對三個按鈕進行初始化
jp=new JPanel();//面板對象
jp.setLayout(new FlowLayout(FlowLayout.CENTER));//流式布局
jp.add(restartgame);//
jp.add(backgame);
jp.add(exitgame);//將三個按鈕添加到面板中
add(jp,BorderLayout.SOUTH);//面板的位置
restartgame.addActionListener(ma);
backgame.addActionListener(ma);
exitgame.addActionListener(ma);//將三個按鈕事件源進行監(jiān)聽
add(chessbord);//添加棋盤
pack();//框架大小的自適應
}
public static void main(String[] args) {
ChessJFrame jf=new ChessJFrame();//聲明框架對象
jf.setVisible(true);//可見
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設置關閉方式
jf.setLocationRelativeTo(null);//將面板置中
}
private class MyActLister implements ActionListener{//事件監(jiān)聽內部類
@Override
public void actionPerformed(ActionEvent e) {
Object obj=e.getSource();//獲取事件源
if(obj==restartgame) {//重新開始事件
System.out.println("重新開始");
chessbord.restartgame();
}
else if(obj==backgame) {//悔棋事件
System.out.println("悔棋");
chessbord.backgame();
}else if(obj==exitgame) {//退出游戲事件
System.exit(0);
}
}
}
}
最后一個棋盤類是最復雜的,也是最重要的一個類,它繼承的JTable類和兩個鼠標事件接口,棋盤類里有畫圖函數(shù),判單輸贏函數(shù)和鼠標處理事件,
先說畫圖函數(shù),它對棋盤進行畫圖,對棋子進行畫圖,要想弄清楚其中的關系,畫一個九宮格自己比劃比劃,
畫圖函數(shù)調用的畫直線函數(shù)方法,畫圓圈方法,畫方框方法;
protected void paintComponent(Graphics g) {//畫棋盤和棋子
super.paintComponent(g);
for(int i=0;i<=ROWS;i ) {//畫棋盤的行數(shù)
g.drawLine(MARGIN, MARGIN i*GRID_SPAN, MARGIN COLS*GRID_SPAN, MARGIN i*GRID_SPAN);
}
for(int i=0;i<=COLS;i ) {//畫棋盤的列數(shù)
g.drawLine(MARGIN i*GRID_SPAN, MARGIN, MARGIN i*GRID_SPAN, MARGIN ROWS*GRID_SPAN);
}
for (int i = 0; i < chessCount; i ) {//畫棋子
int form=chessList[i].getForm();//判斷是什么形狀
int xpos=chessList[i].getX()*GRID_SPAN MARGIN 20;//棋子的X的坐標
int ypos=chessList[i].getY()*GRID_SPAN MARGIN 20;//棋子的y的坐標
if(form==1) {//畫圓圈
g.drawOval(xpos,ypos, GRID_SPAN/2, GRID_SPAN/2);
}else if(form==2) {//畫方框
g.drawRect(xpos, ypos, GRID_SPAN/2, GRID_SPAN/2);
}
}
}
接下來就是鼠標事件,鼠標事件又分為鼠標移動事件和鼠標按下事件,
鼠標移動事件用來設置鼠標光標的,當光標在棋盤外,所在位置有棋子時或游戲結束時設置為默認形狀;
代碼如下;
?
public void mouseMoved(MouseEvent e) {//鼠標移動事件
int x1=(e.getX()-MARGIN)/GRID_SPAN;//棋子x的坐標
int y1=(e.getY()-MARGIN)/GRID_SPAN;//棋子y的坐標
if(x1<0||x1>ROWS-1||y1<0||y1>COLS-1||findchess(x1,y1)||gameover) {//判斷鼠標光標是否在棋盤外,是否所在位置有棋子,是否游戲結束
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));//如果是,設置為默認形狀
}else {//如果不是,則設置為手形
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
?
鼠標按下事件,是用來下棋子的,并判斷棋子是否勝利,是否平局;
代碼如下;
public void mousePressed(MouseEvent e) {//鼠標按下事件
if(gameover)//游戲結束不能下
return ;
int form=start?1:2;
int xindex=(e.getX()-MARGIN)/GRID_SPAN;
int yindex=(e.getY()-MARGIN)/GRID_SPAN;
if(xindex<0||xindex>ROWS-1||yindex<0||yindex>COLS-1||findchess(xindex, yindex)) {
return ;//在棋盤外,所在位置有棋子,不能下
}
Chess ch=new Chess(xindex,yindex,form);//棋子對象
chessList[chessCount ]=ch;//存放在棋子對象數(shù)組里
repaint();//重畫
if(win(xindex,yindex)) {//如果游戲勝利,輸出以下信息
String msg=String.format("恭喜 %s贏了",start?"圓圈":"方框");
JOptionPane.showMessageDialog(this, msg);
gameover=true;
}else if(chessCount==ROWS*COLS&&gameover==false) {//如果棋子下滿,并且沒有勝利,輸出以下信息
String msg=String.format("旗鼓相當,加油");
JOptionPane.showMessageDialog(this, msg);
gameover=true;
}
start=!start;//改變形狀
}
最后是判斷棋子是否勝利的代碼,個人覺得這是最難的地方;
判斷井字棋是否勝利時,當棋子個數(shù)小于5時不用判斷棋子是否勝利,棋子數(shù)不夠;
判斷主對角線上的棋子時,根據棋子的坐標我們可以知道主對角線上的x坐標與y坐標是相等的;
接下來就是遍歷棋子數(shù)組中的棋子是否有x坐標與Y坐標相等的;
有的話就判斷是否和當前所下棋子是否相同,是的話,數(shù)目加一,當數(shù)目為三時,說明游戲中有棋子勝利;
根據這個關系寫出可以下代碼;
if(xindex==yindex) {//主對角線上的棋子
for(int i=0;i
if(chessList[i].getX()==chessList[i].getY()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子個數(shù)是否為三
return true;
}else {
Count=0;
}
判斷反對角線上的棋子,放對角線的棋子x坐標和y坐標相加等于同一個數(shù);
判斷反對角線上的棋子原理和主對角線上的原理差不多,這里就不多說了;
if(xindex yindex==2) {//反對角線上的棋子
for(int i=0;i
if(chessList[i].getX() chessList[i].getY()==2) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
}
接下來就是判斷棋子所在行和列是否有相同連續(xù)的三個棋子;
根據坐標關系我們可知;同一列的坐標,它們的x坐標值相等,同一行的坐標,它們的y坐標相等;
以列為例,我們可以根據所下棋子的索引來對棋子所在的列進行遍歷;
拿出當前所下棋子的x索引值,然后遍歷棋子對象中有沒有和當前棋子x索引相同的值,有的話說明該棋子是和所下棋子在同一列
然后進行判斷,同一列有沒有連續(xù)相同的三個棋子;有的話則當前棋子勝利;
行和列的判斷代碼如下;
for(int i=0;i
if(xindex==chessList[i].getX()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
for(int i=0;i
if(yindex==chessList[i].getY()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
棋盤類三個比較重要的部分已經說完了,接下來我會貼出完整的棋盤類代碼,大家再接再厲;
?
import java.awt.*;
import java.awt.event.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
/*
* 井字棋的棋盤類
* 棋盤類繼承了面板類和鼠標事件接口
*/
public class Chessbord extends JPanel implements MouseListener,MouseMotionListener{
private static int MARGIN=30;//面板與框架之間的間距
private static int ROWS=3;//行數(shù)
private static int COLS=3;//列數(shù)
private static int GRID_SPAN=80;//網格間距
Chess[] chessList=new Chess[ROWS*COLS];//棋子數(shù)組,存放棋子對象
int chessCount=0;//棋子個數(shù)
boolean start=true;//默認圓圈先下
boolean gameover=false;//游戲結束
public Chessbord() {//構造函數(shù)
setBackground(Color.GRAY);//設置背景顏色
addMouseListener(this);
addMouseMotionListener(this);//添加鼠標事件
}
@Override
protected void paintComponent(Graphics g) {//畫棋盤和棋子
super.paintComponent(g);
for(int i=0;i<=ROWS;i ) {//畫棋盤的行數(shù)
g.drawLine(MARGIN, MARGIN i*GRID_SPAN, MARGIN COLS*GRID_SPAN, MARGIN i*GRID_SPAN);
}
for(int i=0;i<=COLS;i ) {//畫棋盤的列數(shù)
g.drawLine(MARGIN i*GRID_SPAN, MARGIN, MARGIN i*GRID_SPAN, MARGIN ROWS*GRID_SPAN);
}
for (int i = 0; i < chessCount; i ) {//畫棋子
int form=chessList[i].getForm();//判斷是什么形狀
int xpos=chessList[i].getX()*GRID_SPAN MARGIN 20;//棋子的X的坐標
int ypos=chessList[i].getY()*GRID_SPAN MARGIN 20;//棋子的y的坐標
if(form==1) {//畫圓圈
g.drawOval(xpos,ypos, GRID_SPAN/2, GRID_SPAN/2);
}else if(form==2) {//畫方框
g.drawRect(xpos, ypos, GRID_SPAN/2, GRID_SPAN/2);
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {//鼠標移動事件
int x1=(e.getX()-MARGIN)/GRID_SPAN;//棋子x的坐標
int y1=(e.getY()-MARGIN)/GRID_SPAN;//棋子y的坐標
if(x1<0||x1>ROWS-1||y1<0||y1>COLS-1||findchess(x1,y1)||gameover) {//判斷鼠標光標是否在棋盤外,是否所在位置有棋子,是否游戲結束
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));//如果是,設置為默認形狀
}else {//如果不是,則設置為手形
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
private boolean findchess(int x1, int y1) {//判斷所在位置是否有棋子
for (Chess chess : chessList) {
if(chess!=null&&chess.getX()==x1&&chess.getY()==y1) {
return true;
}
}
return false;
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {//鼠標按下事件
if(gameover)//游戲結束不能下
return ;
int form=start?1:2;
int xindex=(e.getX()-MARGIN)/GRID_SPAN;
int yindex=(e.getY()-MARGIN)/GRID_SPAN;
if(xindex<0||xindex>ROWS-1||yindex<0||yindex>COLS-1||findchess(xindex, yindex)) {
return ;//在棋盤外,所在位置有棋子,不能下
}
Chess ch=new Chess(xindex,yindex,form);//棋子對象
chessList[chessCount ]=ch;//存放在棋子對象數(shù)組里
repaint();//重畫
if(win(xindex,yindex)) {//如果游戲勝利,輸出以下信息
String msg=String.format("恭喜 %s贏了",start?"圓圈":"方框");
JOptionPane.showMessageDialog(this, msg);
gameover=true;
}else if(chessCount==ROWS*COLS&&gameover==false) {//如果棋子下滿,并且沒有勝利,輸出以下信息
String msg=String.format("旗鼓相當,加油");
JOptionPane.showMessageDialog(this, msg);
gameover=true;
}
start=!start;//改變形狀
}
private boolean win(int xindex,int yindex) {//判斷游戲是否勝利
if(chessCount<5) {//當棋子小于5時不用判斷
return false;
}
int x=start?1:2;//判斷棋子形狀
int Count=0;//統(tǒng)計連續(xù)棋子數(shù)
if(xindex==yindex) {//主對角線上的棋子
for(int i=0;i
if(chessList[i].getX()==chessList[i].getY()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子個數(shù)是否為三
return true;
}else {
Count=0;
}
}
if(xindex yindex==2) {//反對角線上的棋子
for(int i=0;i
if(chessList[i].getX() chessList[i].getY()==2) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
}
for(int i=0;i
if(xindex==chessList[i].getX()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
for(int i=0;i
if(yindex==chessList[i].getY()) {
if(chessList[i].getForm()==x) {
Count ;
}else
break;
}
}
if(Count==3) {//判斷連續(xù)棋子數(shù)是否為三
return true;
}else {
Count=0;
}
return false;//否則返回false
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void restartgame() {//重新開始函數(shù)
for (int i = 0; i < chessList.length; i ) {
chessList[i]=null;
}
chessCount=0;
gameover=false;
start=true;//一切恢復為初始狀態(tài)
repaint();//重畫
}
public void backgame() {//悔棋函數(shù)
if(gameover) {//如果游戲結束,不能悔棋
return ;
}
if(chessCount==0) {//如果棋子個數(shù)為0,不能悔棋
return ;
}
chessList[chessCount-1]=null;
chessCount--;
start=!start;//改變形狀
repaint();//重畫
}
public Dimension getPreferredSize() {//畫矩形面板
return new Dimension(MARGIN*2 ROWS*GRID_SPAN,MARGIN*2 COLS*GRID_SPAN);
}
}
?
井字棋代碼到此結束;
來源:http://www.icode9.com/content-1-135351.html
總結
以上是生活随笔為你收集整理的井字棋java代码_JAVA 井字棋的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# Winfrom 右键菜单
- 下一篇: linpack测试软件,服务器性能测试(