java五子棋的實現(1)
阿新 • • 發佈:2018-12-18
基本介面的實現 建立主窗體,為其新增五子棋基本功能的按鈕:開始遊戲,悔棋,認輸,對戰方式,並繪製棋盤,因為棋盤和棋子的引數是恆定的,我們定義一個介面
public interface GoBangInformation {
public static final int X=50,Y=100,SIZE=35,CHESS_SIZE=33,ROW=15,COLUMN=15;
}
然後讓整個五子棋程式的所有檔案實現該介面,接著繪製棋盤
private void drawTable(Graphics g) { g.setColor(Color.BLACK); for(int i=0;i<ROW;i++) { g.drawLine(X, Y+SIZE*i, X+SIZE*(COLUMN-1), Y+SIZE*i); } for(int i=0;i<COLUMN;i++) { g.drawLine(X+SIZE*i, Y ,X+SIZE*i, Y+SIZE*(ROW-1)); } }
下棋資料的儲存 1.首先為了儲存整個棋盤的資料,我定義了一個二維陣列public static int [][] chessTable=new int[ROW][COLUMN];來儲存每個點上的棋子資料(例如:0-無棋子,1-黑棋,2-白棋) 2.為了實現悔棋功能,我們需要記錄每一步的棋子位置,一個index代表第幾步棋, public static int []indxhistory=new int[500]; public static int []indyhistory=new int[500]; 來記錄每一步棋的橫豎座標. 繪製棋子:棋子顏色變更及棋子位置判斷 顏色變更可以用一個flag來判定,每次畫棋子變更一下,把棋子畫在交叉處可以分兩步來進行,先是根據滑鼠點選位置判斷在第幾行第幾列,然後在該交叉點畫棋子,注意每次繪製要判斷該位置是否已有棋子,有才繪製。
public static int getindexx(int tempX) { if(tempX<X+SIZE/2) { return 0; } else if(tempX>X+SIZE*(COLUMN-1)+SIZE/2) { return COLUMN-1; } else { return (tempX-X+SIZE/2)/SIZE+1; } } //繪製棋子,若該位置有棋子則返回false public static int getindexy(int tempY) { if(tempY<Y+SIZE/2) { return 0; } else if(tempY>Y+SIZE*(ROW-1)+SIZE/2) { return ROW-1; } else { return (tempY-Y+SIZE/2)/SIZE+1; } } public static boolean drawOneChess(Graphics g,int indx,int indy,boolean flag) { if(chessTable[indx][indy]==1) { if(flag) { chessTable[indx][indy]=2; g.setColor(Color.BLACK); } else { chessTable[indx][indy]=3; g.setColor(Color.WHITE); } g.fillOval(X+(indx)*SIZE-CHESS_SIZE/2, Y+(indy)*SIZE-CHESS_SIZE/2, CHESS_SIZE, CHESS_SIZE); return true; } return false; }
悔棋功能的實現 1.根據棋子歷史修改現有棋盤chessTable上每一個點上的棋子有無及顏色。
public void actionPerformed(ActionEvent e) {
String ac=e.getActionCommand();
//悔棋實現
if(ac.equals("悔棋")) {//在主介面用setActionCommand()為元件取名。
//人人對戰的悔棋處理
if(gameStart==1&&gameType==0) {
setG();
if(index>0) {
index--;
chessTable[indxhistory[index]][indyhistory[index]]=1;
frame.paint(graphics);
}
else {
//如果還沒開始下就什麼都不做
}
}
//人機對戰的悔棋處理,每次悔兩步
if(gameStart==1&&gameType==1) {
setG();
if(index>0) {
index--;
chessTable[indxhistory[index]][indyhistory[index]]=1;
index--;
chessTable[indxhistory[index]][indyhistory[index]]=1;
frame.paint(graphics);
}
else {
//如果還沒開始下就什麼都不做
}
}
}
}
2.根據chessTable上的棋盤佈局重繪棋盤
public void paint(Graphics g) {
super.paint(g);
drawTable(g);
if(test==1)//棋盤初始化
DrawChess.refreTable();
else
DrawChess.drawChess(g);
test++;
}
3.具體的重繪方法
public static void drawChess(Graphics g) {
for(int i=0;i<15;i++) {
for(int k=0;k<15;k++) {
if(chessTable[i][k]==2) {
g.setColor(Color.BLACK);
g.fillOval(X+i*SIZE-CHESS_SIZE/2, Y+k*SIZE-CHESS_SIZE/2, CHESS_SIZE, CHESS_SIZE);
}
else if(chessTable[i][k]==3) {
g.setColor(Color.WHITE);
g.fillOval(X+i*SIZE-CHESS_SIZE/2, Y+k*SIZE-CHESS_SIZE/2, CHESS_SIZE, CHESS_SIZE);
}
else {
}
}
}
}
輸贏判斷
判斷輸贏的方法是在每一次畫完棋子後,分別判斷橫,豎,左斜,右斜四條線上是否有相鄰的五顆棋子,若有,則輸出勝利訊號,結束遊戲。 對橫線的處理
private static boolean judgeRow(int indx,int indy) {
boolean result=false;
int flag=0;//記錄相同棋子個數
for(int i=indx-1;i>0;i--) {
if(chessTable[i][indy]==chessTable[indx][indy]) {
flag++;
}
else {
break;
}
}
for(int i=indx+1;i<ROW;i++) {
if(chessTable[i][indy]==chessTable[indx][indy]) {
flag++;
}
else {
break;
}
}
if(flag>=4) {
result=true;
}
return result;
}
結束遊戲的操作
if(flag) {//玩家為黑
winMessage="黑方贏了";
JOptionPane.showMessageDialog(null,winMessage, "遊戲結束", JOptionPane.INFORMATION_MESSAGE);//彈窗提示
refresh();//清空棋盤並重繪
return true;//返回判斷結果,若為false,則繼續遊戲
}
else {
winMessage="黑方輸了";
JOptionPane.showMessageDialog(null,winMessage , "遊戲結束", JOptionPane.INFORMATION_MESSAGE);
refresh();
return true;
}
private void refresh() {
gameStart=0;
flag=true;
DrawChess.refreTable();
if(graphics==null)
setG();
index=0;
frame.paint(graphics);
}