奥赛罗(黑白棋)Java实现

奥赛罗是两人在8×8的棋盘上玩的游戏,棋子的一面是白色,另一面是黑色。下棋时,先下的玩家将棋子的白面朝上,后下的玩家将棋子的黑面朝上。玩家交替地将棋子放在棋盘的空位上。在放置棋子时,玩家必须夹住对方的至少一个棋子。当棋子沿横、纵和对角线方向排在一条直线上,并且两端的棋子都是当前玩家的颜色时,称棋子被夹住了,见下图。当玩家下了一步之后,所有被夹住的对方棋子都将被翻过来,从而变为当前玩家的棋子(有可能在一步中夹住多行棋子)。

 

 白色的合法移动 
(2,3),(3,3),(3,5),(3,6)
(6,2),(7,3),(7,4),(7,5)

 

 白方下在(7,3)之后的棋盘局面

写一个程序,读入若干奥赛罗游戏。输入的第一行是要处理的游戏个数,每个游戏有棋盘局面及其后所跟的一系列命令组成。

棋盘局面由9行组成,前8行给出了棋盘的当前状态。这8行每行包括8个字符,所有这些字符是如下之一: ‘-’ 表示空格子 ‘B’ 表示放有黑色棋子的格子 ‘W’ 表示放有白色棋子的格子 第9行是‘B’或‘W’之一,以指出当前游戏者。你可以假定数据是合法格式的。 命令可以是为当前玩家列处所有可能的走步,走一步或退出当前游戏。

每条命令占一行且无空格。命令的格式如下:

1. 为当前游戏者列出所有可能的走步: 命令是‘L’,在命令行的第一列。 程序应检查棋盘并用格式(x, y)打印当前玩家的所有合法走步,这里x代表合法走步的行号,y代表列号。这些走步应当被按行优先顺序打印,也就是说: (1) 如果j大于i,则所有行号是i的合法走步将在所有行号是j的合法走步之前打印; (2) 如果有多于一个的合法走步的行号是i,则这些走步将按列号升序打印。每一个合法走步之间输出没有空格。 (3) 所有的合法走步应当输出在一行上。如果因为当前游戏者不可能夹住任何棋子而不存在合法走步,程序应当打印“No legal move.“信息。

2. 走一步: 命令是‘M’,在命令行的第1列,其后是在第2、3列的两个数字。 这两个数字是放置当前玩家颜色的棋子的格子的行、列号,除非当前游戏者没有合法走步。如果当前玩家没有合法走步,当前游戏者将首先换成另一个游戏者,此走步将是新游戏者的走步。你可以假定此时走步一定是合法的。你应该将变更记录至棋盘,包括加入新棋子和改变所有被夹住棋子的颜色(将棋子翻过来)。走完了此步之后,按 “Black-xx White-yy”的格式(例,Black-1 White-4)打印棋盘上每种颜色的棋子数目,这里xx是棋盘上黑色棋子的数目,yy是棋盘上白色棋子的数目。走完一步后,当前游戏者将换成没有走步的游戏者。

3. 退出当前游戏: 命令是‘Q’,在命令行的第1列。 在这里,用同输入相同的格式打印最后的棋盘局面。这终止了当前游戏的命令输入。 你可以假定命令在语法上是正确的。用一个空行隔开不同游戏的输出,输出中的其他地方不得出现空行。请见下图输入样例与输出样例。

input:

 

 output:

 

 分析:明确了游戏规则写起来就容易,重点是对棋子落点的判断,还有要熟悉对String的操作。

//Main.java
package test;
import test.Game;
/*
请注意:
**********************************************************************
*********以下为主类文件中的代码,请根据主类代码编写Game类和Board类********
*****************主类代码已经编写完成并隐藏,无需再次编写****************
***Game类和Board类已经建好,请同学们点击左上角代码文件后的小三角进行切换***
**********************************************************************
*/
import java.util.Scanner;
public class Main{

  public static void main(String[] args) {
    Scanner myScanner = new Scanner(System.in);
    int gameRounds = myScanner.nextInt();
    for (int i = 0; i < gameRounds; i++) {
      Game game = new Game();
      game.readGame(myScanner);
      game.process(myScanner);
    }
  }
}

  

//Game.java
package test;
import java.util.Scanner;
import test.Board;
import java.util.List;
import java.util.ArrayList;

public class Game {
	private Board board = new Board();    //棋盘
	private char currentPlayer = 'B';   //轮到下棋的一方

	static List<String> action = new ArrayList<>();
	public void readGame(Scanner scanner) {
		board.init(0,0);
		action.clear();
		String str;
		for(int i=0;i<8;i++)
		{
			str = scanner.next();
			for(int j=0;j<8;j++)
				board.setboard(i,j,str.charAt(j));
		}
		currentPlayer = scanner.next().charAt(0);
		str = " ";
		while(str.charAt(0) != 'Q')
		{
			str = scanner.next();
			if(str.charAt(0) == 'L')
				action.add(board.scan(currentPlayer));
			else if(str.charAt(0) == 'M')
			{
				int x = Integer.parseInt(str.substring(1,2))-1;
				int y = Integer.parseInt(str.substring(2))-1;
				if(board.scan(currentPlayer).equals("No legal move."))
				{
					if(currentPlayer == 'W')
						currentPlayer = 'B';
					else
						currentPlayer = 'W';   //change for once
				}
				board.setboard(x,y,currentPlayer);
				board.refresh(x,y,currentPlayer);    //refresh board
				String record = "Black-"+board.count('b')+" White-"+board.count('w');
				action.add(record);
				if(currentPlayer == 'W')   //change again
					currentPlayer = 'B';
				else
					currentPlayer = 'W';
			}
		}
	}
	public void process(Scanner scanner) {
		for(int i=0;i<action.size();i++)
			System.out.println(action.get(i));
		board.getboard();
	}
}

  

//Board.java
package test;
//import java.util.Scanner;

public class Board {
	  //棋盘的数据
	  private char[][] board = new char[8][8];
	  private int wnum;
	  private int bnum;
	  
	  private int dire1(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i-1;k>=0;k--)
		  {
			  if(board[k][j] == '-')
				  break;
			  else if(board[k][j] == sym)
			  {
				  if(k == i-1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire2(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i+1;k<=7;k++)
		  {
			  if(board[k][j] == '-')
				  break;
			  else if(board[k][j] == sym)
			  {
				  if(k == i+1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire3(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=j-1;k>=0;k--)
		  {
			  if(board[i][k] == '-')
				  break;
			  else if(board[i][k] == sym)
			  {
				  if(k == j-1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire4(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=j+1;k<=7;k++)
		  {
			  if(board[i][k] == '-')
				  break;
			  else if(board[i][k] == sym)
			  {
				  if(k == j+1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire5(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i-1,l=j-1;k>=0&&l>=0;k--,l--)
		  {
			  if(board[k][l] == '-')
				  break;
			  else if(board[k][l] == sym)
			  {
				  if(k == i-1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire6(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i+1,l=j+1;k<=7&&l<=7;k++,l++)
		  {
			  if(board[k][l] == '-')
				  break;
			  else if(board[k][l] == sym)
			  {
				  if(k == i+1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire7(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i-1,l=j+1;k>=0&&l<=7;k--,l++)
		  {
			  if(board[k][l] == '-')
				  break;
			  else if(board[k][l] == sym)
			  {
				  if(k == i-1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  private int dire8(int i,int j,char sym)
	  {
		  int flag =0;
		  for(int k=i+1,l=j-1;k<=7&&l>=0;k++,l--)
		  {
			  if(board[k][l] == '-')
				  break;
			  else if(board[k][l] == sym)
			  {
				  if(k == i+1)
					  break;
				  else
				  {
					  flag = 1;
					  break;
				  }
			  }
		  }
		  return flag;
	  }
	  
	  public void init(int a,int b)
	  {
		  wnum = a;
		  bnum = b;
	  }
	  
	  public void setboard(int x,int y,char c)
	  {
		  if(c == 'B' && board[x][y] != 'W')
			  bnum++;
		  else if(c == 'W' && board[x][y] != 'B')
			  wnum++;
		  else if(c == 'B' && board[x][y] == 'W')
		  {
			  bnum++;
			  wnum--;
		  }
		  else if(c == 'W' && board[x][y] == 'B')
		  {
			  bnum--;
			  wnum++;
		  }
		  board[x][y] = c;
	  }
	  
	  public void getboard()
	  {
		  for(int i=0;i<8;i++)
			  for(int j=0;j<8;j++)
			  {
				  System.out.print(board[i][j]);
				  if(j == 7)
					  System.out.println();
			  }
	  }
	  
	  public int count(char sym)
	  {
		  if(sym == 'w')
			  return wnum;
		  else
			  return bnum;
	  }
	  
	  public void refresh(int i,int j,char sym)
	  {
		  if(dire1(i,j,sym) == 1)
		  {
			  for(int k=i-1;k>=0;k--)
			  {
				  if(board[k][j] == sym)
					  break;
				  setboard(k,j,sym);
				  refresh(k,j,sym);   //deep search
			  }
		  }
		  if(dire2(i,j,sym) == 1)
		  {
			  for(int k=i+1;k<=7;k++)
			  {
				  if(board[k][j] == sym)
					  break;
				  setboard(k,j,sym);
				  refresh(k,j,sym);
			  }
		  }
		  if(dire3(i,j,sym) == 1)
		  {
			  for(int k=j-1;k>=0;k--)
			  {
				  if(board[i][k] == sym)
					  break;
				  setboard(i,k,sym);
				  refresh(i,k,sym);
			  }
		  }
		  if(dire4(i,j,sym) == 1)
		  {
			  for(int k=j+1;k<=7;k++)
			  {
				  if(board[i][k] == sym)
					  break;
				  setboard(i,k,sym);
				  refresh(i,k,sym);
			  }
		  }
		  if(dire5(i,j,sym) == 1)
		  {
			  for(int k=i-1,l=j-1;k>=0&&l>=0;k--,l--)
			  {
				  if(board[k][l] == sym)
					  break;
				  setboard(k,l,sym);
				  refresh(k,l,sym);
			  }
		  }
		  if(dire6(i,j,sym) == 1)
		  {
			  for(int k=i+1,l=j+1;k<=7&&l<=7;k++,l++)
			  {
				  if(board[k][l] == sym)
					  break;
				  setboard(k,l,sym);
				  refresh(k,l,sym);
			  }
		  }
		  if(dire7(i,j,sym) == 1)
		  {
			  for(int k=i-1,l=j+1;k>=0&&l<=7;k--,l++)
			  {
				  if(board[k][l] == sym)
					  break;
				  setboard(k,l,sym);
				  refresh(k,l,sym);
			  }
		  }
		  if(dire8(i,j,sym) == 1)
		  {
			  for(int k=i+1,l=j-1;k<=7&&l>=0;k++,l--)
			  {
				  if(board[k][l] == sym)
					  break;
				  setboard(k,l,sym);
				  refresh(k,l,sym);
			  }
		  }
	  }
	  
	  public String scan(char sym)
	  {
		  String str = "";
		  for(int i=0;i<8;i++)
			  for(int j=0;j<8;j++)
			  {
				  if(board[i][j] == '-')
				  {
					  if(dire1(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire2(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire3(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire4(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire5(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire6(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire7(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  else if(dire8(i,j,sym) == 1)
						  str += "("+(i+1)+","+(j+1)+")";
					  //eight directions
				  }
			  }
		  if(str == "")
			  return "No legal move.";
		  else
			  return str;
	  }
}

  

运行结果:

 

posted @ 2021-03-25 16:52  梵蒂冈宝石  阅读(1017)  评论(0编辑  收藏  举报