1. 程式人生 > >五子棋基礎演算法及勝利判定演算法(無AI)

五子棋基礎演算法及勝利判定演算法(無AI)

這篇文章只是簡單的繪製了一個棋盤,通過輸入座標(格式舉例: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的形式");
			
		}
		
		
	}

}