import java.io.*;
import java.util.*;
public class Gobang{
//定义棋盘的大小
private static final int BOARD_SIZE = 15;
//用二维数组充当棋盘
private String[][] board;
//用来画棋盘的符号("+"),此符号处代表无棋子
private final String POINT = "+";
//黑棋子
private final String BLACK = "●";
//白棋子
private final String WHITE = "○";
public static void main(String args[]) throws IOException{
Gobang gb = new Gobang();
gb.initBoard();
gb.printBoard();
gb.start();
}
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] = POINT;
}
}
}
//在控制台输出棋盘
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.print("\n");
}
}
//游戏开始
public void start() throws IOException{
System.out.println("请输入您下棋的坐标,应以x,y的格式:");
//获取从键盘输入的方法
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String inputStr = "";
//键盘输入后按回车能被bufferedReader读取到
while((inputStr = bufferedReader.readLine()) != null){
String[] posStrArr = inputStr.split(",");
int x = 0;
int y = 0;
try{
x = Integer.parseInt(posStrArr[0]);
y = Integer.parseInt(posStrArr[1]);
}catch(NumberFormatException e){
//装换错误说明输入格式不对,重新输入
System.out.println("输入的格式不正确!");
continue;
}
if(!pointValid(x - 1,y - 1)){
System.out.println("您输入的棋子坐标无效,请重输!");
//无效直接跳过后面代码
continue;
}
//对应位置用●赋值,代表一枚棋子
board[x - 1][y - 1] = BLACK;
if(scan()){
System.out.println("玩家胜利!游戏结束");
printBoard();
break;
}
/*
电脑随机生成两个整数,作为电脑下棋的坐标,赋值给board数组
还涉及:
1.坐标的有效性,只能是数字,不能超出棋盘的范围
2.下棋的点,不能重复下棋
3.每次下棋后需要扫描谁赢了
*/
computer();//需要完善的点:可以选择谁先下而不是默认的玩家先下
if(scan()){
System.out.println("电脑胜利!游戏结束");
printBoard();
break;
}
printBoard();
System.out.println("请输入您下棋的坐标,应以x,y的格式(原点为左上角,x正方向向下,y正方向向右):");
}
}
//电脑下棋的方法
private void computer(){
//已满足生成点的坐标在棋盘内
Random random = new Random();
int x = random.nextInt(BOARD_SIZE);
int y = random.nextInt(BOARD_SIZE);
//有效性验证
while(!pointValid(x,y)){
//无效坐标重新生成
x = random.nextInt(BOARD_SIZE);
y = random.nextInt(BOARD_SIZE);
}
board[x][y] = WHITE;//需要完善的点:可以让玩家选择棋子,而不是默认玩家黑,电脑白
}
/**
*
* 验证下棋点的有效性
* 1.验证下棋点是否超出棋盘范围(玩家下棋时需要验证,电脑这一步其实可以不验证)
* 2.验证下棋的点是否已存在棋子
* @param x 横坐标(索引 0开始)
* @param y 纵坐标(索引 0开始)
* @return 坐标的有效性 有效:true,无效:false
*
* java语法: javadoc只处理public protected修饰的类、接口、方法、成员变量、
* 构造函数、和内部类之前的文档注释(此处private,所以不会处理)
*/
private boolean pointValid(int x,int y){
//验证下棋点是否超出棋盘范围(玩家下棋时需要验证,电脑这一步其实可以不验证,因为它生成的位置就在范围内)
if(x >= BOARD_SIZE || y >= BOARD_SIZE || x < 0 || y < 0)
return false;
//验证下棋的点是否已存在棋子
if(board[x][y] != POINT){
//已存在棋子
return false;
}
return true;
}
/**
难点:扫描算法(自己写的比较蠢的办法...智商不够用..哈哈)
扫描是否有五个相同棋子连成一条线(—|\/)
分析:
一条线有四种情况—|\/:
原点为左上角,x正方向向下,y正方向向右
-: x相等 y从左到右依次加1
|: y相等 x从上到下依次加1
\: 从左上到右下,xy都依次加1
/: 从右上到左下,x从上到下依次加1,y从右到左依次减1
@return 有返回true,没有返回false
*/
private boolean scan(){
for(int i = 0; i < BOARD_SIZE; i ++){
for(int j = 0; j < BOARD_SIZE; j ++){
if(board[i][j] != POINT){
//有棋子
if(board[i][j] == BLACK){
if(getFive1(i,j,BLACK) || getFive2(i,j,BLACK) || getFive3(i,j,BLACK) || getFive4(i,j,BLACK))
return true;
}
//白棋子
if(board[i][j] == WHITE){
if(getFive1(i,j,WHITE) || getFive2(i,j,WHITE) || getFive3(i,j,WHITE) || getFive4(i,j,WHITE))
return true;
}
}
}
}
return false;
}
// "-"
private boolean getFive1(int x,int y,String point){
boolean flag = true;
try{
for(int m = 1; m <= 4 && flag; m ++){
if(board[x][y+m]!=point){
flag = false;
}
}
}catch(ArrayIndexOutOfBoundsException e){
flag = false;
}
return flag;
}
// "|"
private boolean getFive2(int x,int y,String point){
boolean flag = true;
try{
for(int m = 1; m <= 4 && flag; m ++){
if(board[x+m][y]!=point){
flag = false;
}
}
}catch(ArrayIndexOutOfBoundsException e){
flag = false;
}
return flag;
}
// "/"
private boolean getFive3(int x,int y,String point){
boolean flag = true;
try{
for(int m = 1; m <= 4 && flag; m ++){
if(board[x+m][y-m]!=point){
flag = false;
}
}
}catch(ArrayIndexOutOfBoundsException e){
flag = false;
}
return flag;
}
// "\"
private boolean getFive4(int x,int y,String point){
boolean flag = true;
try{
for(int m = 1; m <= 4 && flag; m ++){
if(board[x+m][y+m]!=point){
flag = false;
}
}
}catch(ArrayIndexOutOfBoundsException e){
flag = false;
}
return flag;
}
}