五子棋基礎演算法及勝利判定演算法(無AI)
阿新 • • 發佈:2019-02-13
這篇文章只是簡單的繪製了一個棋盤,通過輸入座標(格式舉例:3,4)來下棋,然後就是勝利判定演算法。我最剛開始的演算法會出現陣列越界問題,也就是說當棋子下在棋盤最靠邊的一圈時就會出現陣列越界異常,後來大改了一遍,解決了這個問題。下面是正確的程式碼:
下面是之前會出現陣列越界錯誤的程式碼,雖然存在問題,但思路是對的,也放上來吧。import java.io.BufferedReader; import java.io.InputStreamReader; public class five { //定義棋盤的大小 private static int BOARD_SIZE=15; //定義一個二維陣列用於顯示棋盤 private String[][] board; //定義一個二維陣列用於記錄座標 private int[][]xy=new int[225][2]; //判斷是否已勝利 private int[][]idx=new int[15][15]; //count為勝利的步數,每種勝利型別應重置count int count=0; //x,y為座標,q為勝利型別,id來判定已經經歷過的點,每種勝利切換時也應該重置count boolean win=false; public void isSuccess(int x,int y,int q,int id) { //以下整個條件判斷是為了判斷水平方向五子勝利 //判斷是否越界 if(x<0||x>=14||y<0||y>=14) return; //不是棋子或已訪問的格子 if(idx[x][y]!=0||board[x][y]!="●") return; idx[x][y]=id; count++; //System.out.println("count"+count); if(count==5) { System.out.println("您已勝利!"); win=true; return; } switch(q) { //橫向勝利判斷 case 0: for(int i=-1;i<2;i++) { if(i!=0) isSuccess(x+i,y,0,id); } break; //縱向勝利判斷 case 1: for(int i=-1;i<2;i++) { if(i!=0) isSuccess(x,y+i,1,id); } break; //從左上到右下 case 2: for(int i=-1;i<2;i++) { if(i!=0) isSuccess(x+i,y+i,2,id); } break; case 3: //以下用於判斷從右上到左下的勝利 for(int i=-1;i<2;i++) { if(i!=0) isSuccess(x-i,y+i,3,id); } break; } } //初始化棋盤 public void initBoard() { board=new String[BOARD_SIZE][BOARD_SIZE]; for(int i=0;i<BOARD_SIZE;i++) { for(int j=0;j<BOARD_SIZE;j++) { board[i][j]="+"; //board[i][j]="➕"; } } } //控制檯輸出棋盤的方法 public void printBoard(){ for(int i=0;i<BOARD_SIZE;i++) { for(int j=0;j<BOARD_SIZE;j++) { System.out.print(board[i][j]); } System.out.println(); } } public static void main(String [] args)throws Exception { five gb=new five(); gb.initBoard(); gb.printBoard(); int id=1; int step=0; //用於獲得鍵盤輸入的方法 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String inputStr=null; while((inputStr=br.readLine())!=null) { String[] posStrArr=inputStr.split(","); int xPos=Integer.parseInt(posStrArr[0]); int yPos=Integer.parseInt(posStrArr[1]); if(gb.board[xPos-1][yPos-1]=="●") { System.out.println("該點已有棋子,請選擇其它落點"); gb.printBoard(); continue; } gb.xy[step][0]=xPos-1; gb.xy[step][1]=yPos-1; step++; gb.board[xPos-1][yPos-1]="●"; gb.printBoard(); for(int i=0;i<step;i++) { for(int j=0;j<4;j++) {if(gb.win) return; gb.isSuccess(gb.xy[i][0], gb.xy[i][1], j, id++); // System.out.println("i="+i+"; j="+j); for(int a=0;a<15;a++) { for(int b=0;b<15;b++) gb.idx[a][b]=0; } gb.count=0; } } System.out.println("請輸入您下棋的座標,應以x,y的形式"); } } }
import java.io.BufferedReader; import java.io.InputStreamReader; public class Gobang { //定義棋盤的大小 private static int BOARD_SIZE=15; //定義一個二維陣列用於顯示棋盤 private String[][] board; //初始化棋盤 public void initBoard() { board=new String[BOARD_SIZE][BOARD_SIZE]; for(int i=0;i<BOARD_SIZE;i++) { for(int j=0;j<BOARD_SIZE;j++) { board[i][j]="+"; //board[i][j]="➕"; } } } //控制檯輸出棋盤的方法 public void printBoard(){ for(int i=0;i<BOARD_SIZE;i++) { for(int j=0;j<BOARD_SIZE;j++) { System.out.print(board[i][j]); } System.out.println(); } } public static void main(String [] args)throws Exception { Gobang gb=new Gobang(); gb.initBoard(); gb.printBoard(); int [] px=new int[225]; int [] py=new int [225]; int count=0; //用於獲得鍵盤輸入的方法 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String inputStr=null; while((inputStr=br.readLine())!=null) { String[] posStrArr=inputStr.split(","); int xPos=Integer.parseInt(posStrArr[0]); int yPos=Integer.parseInt(posStrArr[1]); if(gb.board[xPos-1][yPos-1]=="●") { System.out.println("該點已有棋子,請選擇其它落點"); gb.printBoard(); continue; } px[count]=xPos-1; py[count]=yPos-1; gb.board[xPos-1][yPos-1]="●"; count++; gb.printBoard(); if(count>=5) { for(int i=0;i<count;i++) { int x=px[i]; int y=py[i]; //以下整個條件判斷是為了判斷水平方向五子勝利 if(x!=0&&x!=14&&y!=0&&y!=14) { if(gb.board[x-1][y]=="●"||gb.board[x+1][y]=="●") { //用於記錄已有幾個點相連 int s=1; int a,b; a=x-1; b=x+1; //這個條件判斷為了避免陣列越界 if(a!=0) { while(gb.board[a][y]=="●") { s++; a--; if(a==0) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } //同樣為了避免陣列越界 if(b!=14) { while(gb.board[b][y]=="●") { s++; b++; if(a==14) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } } //以下判斷為了判斷縱向勝利 if(gb.board[x][y-1]=="●"||gb.board[x][y+1]=="●") {//用於記錄已有幾個點相連 int s=1; int a=y-1; int b=y+1; if(a!=0) { while(gb.board[x][a]=="●") { s++; a--; if(a==0) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } if(b!=14) { while(gb.board[x][b]=="●") { s++; b++; if(a==14) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } } //以下用於判斷從左上到右下的勝利 if(gb.board[x-1][y-1]=="●"||gb.board[x+1][y+1]=="●") {//用於記錄已有幾個點相連 int s=1; int a=x-1; int b=y-1; if(a!=0&&b!=0) { while(gb.board[a][b]=="●") { s++; a--; b--; if(a==0||b==0) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } a=x+1; b=y+1; if(b!=14&&a!=14) { while(gb.board[x][b]=="●") { s++; a++; b++; if(a==14||b==14) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } } //以下用於判斷從右上到左下的勝利 if(gb.board[x-1][y+1]=="●"||gb.board[x+1][y-1]=="●") {//用於記錄已有幾個點相連 int s=1; int a=x-1; int b=y+1; if(a!=0&&b!=14) { while(gb.board[a][b]=="●") { s++; a--; b++; if(a==0||b==14) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } a=x+1; b=y-1; if(b!=14&&a!=14) { while(gb.board[x][b]=="●") { s++; a++; b--; if(a==14||b==0) { break; } if(s==5) { System.out.println("您已獲勝"); return; } } } } }else if(x==0) { if(y==0) { } } } } System.out.println("請輸入您下棋的座標,應以x,y的形式"); } } }