奥赛罗(黑白棋)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;
}
}
运行结果:


浙公网安备 33010602011771号