思路
- 二维数组搭建棋盘
- 循环落棋子
- 打印落子后的棋盘
- 判断输赢,是否有直线连接5个棋子的情况
难点
判断输赢是难点,以刚刚落下的棋子为基准,寻找其八个方向的连续的棋子的数量,然后对在一条直线的棋子数量求和,找出最大值,判断是否为5。
代码
package com.dream.test;
import java.util.Arrays;
import java.util.Scanner;
public class Gobang2 {
public static void main(String[] args) {
//棋盘
int length=20;
String[] nums = {"⒈","⒉","⒊","⒋","⒌","⒍","⒎","⒏","⒐","⒑","⒒","⒓","⒔","⒕","⒖","⒗","⒘","⒙","⒚","⒛"};
String add="╋";
String[][] goBang=new String[length][length];
for (int i = 0; i < goBang.length; i++) {
for (int j = 0; j < goBang[i].length; j++) {
if (j==length-1) {
goBang[i][j] = nums[i];
} else if(i==length-1) {
goBang[i][j] = nums[j];
} else {
goBang[i][j] = add;
}
}
}
for (String[] strings : goBang) {
for (String string : strings) {
System.out.print(string);
}
System.out.println();
}
//落子
Scanner sc=new Scanner(System.in);
// 交替落子的标志
boolean flag=true;
while(true){
System.out.println("请"+((flag)?"黑":"白")+"子落子(输入x、y值):");
int x = sc.nextInt();
int y = sc.nextInt();
if(x>length-1 || x<1 || y>length-1 || y<1){
System.out.println("您落子的位置超出棋盘范围,请重新落子:");
continue;
}else if(!goBang[x-1][y-1].equals(add)){
System.out.println("您落子的位置已有棋子,请重新落子:");
continue;
}
goBang[x-1][y-1]=(flag)?"■":"○";
//落子之后打印
for (String[] strings : goBang) {
for (String string : strings) {
System.out.print(string);
}
System.out.println();
}
// 判断输赢,8个方向的连续的棋子长度
int rightCount=right(goBang,x-1,y-1,flag);
int leftCount=left(goBang,x-1,y-1,flag);
int upCount=up(goBang,x-1,y-1,flag);
int downCount=down(goBang,x-1,y-1,flag);
int rightDownCount=rightDown(goBang,x-1,y-1,flag);
int leftDownCount=leftDown(goBang,x-1,y-1,flag);
int leftUpCount=leftUp(goBang,x-1,y-1,flag);
int rightUpCount=rightUp(goBang,x-1,y-1,flag);
// 8个方向组合,变为4个直线方向的连续的棋子长度,装入数组
int[] arr={rightCount+leftCount,upCount+downCount,rightDownCount+leftUpCount,leftDownCount+rightUpCount};
// 求最大长度
int max=max(arr)+1;
// 判断最大长度是否大于等于5,如果大于就获胜了
if(max>=5){
System.out.println(((flag)?"黑":"白")+"子获胜,游戏结束!");
break;
}
// 交替落子
flag=!flag;
}
}
// 八个方向上的连续棋子长度计算
//右
public static int right(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int rightCount=0;
for (int j = yIndex+1; j < goBang.length-1; j++) {
if(goBang[xIndex][j].equals((flag)?"■":"○")){
rightCount++;
continue;
}else{
break;
}
}
return rightCount;
}
//左
public static int left(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int leftCount=0;
for (int j = yIndex-1; j >=0; j--) {
if(goBang[xIndex][j].equals((flag)?"■":"○")){
leftCount++;
continue;
}else{
break;
}
}
return leftCount;
}
//上
public static int up(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int upCount=0;
for (int i = xIndex-1; i >=0; i--) {
if(goBang[i][yIndex].equals((flag)?"■":"○")){
upCount++;
continue;
}else{
break;
}
}
return upCount;
}
//下
public static int down(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int downCount=0;
for (int i = xIndex+1; i <goBang.length-1; i++) {
if(goBang[i][yIndex].equals((flag)?"■":"○")){
downCount++;
continue;
}else{
break;
}
}
return downCount;
}
//右下
public static int rightDown(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int rightDownCount=0;
int i=1;
while(true){
if((xIndex+i)>(goBang.length-1) || (yIndex+i)>(goBang.length-1)){
break;
}
if(goBang[xIndex+i][yIndex+i].equals((flag)?"■":"○")){
rightDownCount++;
i++;
}else{
break;
}
}
return rightDownCount;
}
//左下
public static int leftDown(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int leftDownCount=0;
int i=1;
while(true){
if((xIndex+i)>(goBang.length-1) || (yIndex-i)<0){
break;
}
if(goBang[xIndex+i][yIndex-i].equals((flag)?"■":"○")){
leftDownCount++;
i++;
}else{
break;
}
}
return leftDownCount;
}
//左上
public static int leftUp(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int leftUpCount=0;
int i=1;
while(true){
if((xIndex-i)<0 || (yIndex-i)<0){
break;
}
if(goBang[xIndex-i][yIndex-i].equals((flag)?"■":"○")){
leftUpCount++;
i++;
}else{
break;
}
}
return leftUpCount;
}
//右上
public static int rightUp(String[][] goBang,int xIndex,int yIndex,boolean flag) {
int rightUpCount=0;
int i=1;
while(true){
if((xIndex-i)<0 || (yIndex+i)>(goBang.length-1)){
break;
}
if(goBang[xIndex-i][yIndex+i].equals((flag)?"■":"○")){
rightUpCount++;
i++;
}else{
break;
}
}
return rightUpCount;
}
//求数组最大值
public static int max(int[] arr){
Arrays.sort(arr);
return arr[arr.length-1];
}
}
测试
为了代码的可读性,用面向对象的思维,修改代码的结构如下:
棋类
package com.dream.goBang;
import java.util.Arrays;
import java.util.Scanner;
public class Gobang {
//成员变量
private int length=20;
private String[] nums = {"⒈","⒉","⒊","⒋","⒌","⒍","⒎","⒏","⒐","⒑","⒒","⒓","⒔","⒕","⒖","⒗","⒘","⒙","⒚","⒛"};
private String add="╋";
private String[][] goBang=new String[length][length];
public Gobang() {
init();
print();
}
// 初始化棋盘
public private void init() {
for (int i = 0; i < goBang.length; i++) {
for (int j = 0; j < goBang[i].length; j++) {
if (j==length-1) {
goBang[i][j] = nums[i];
} else if(i==length-1) {
goBang[i][j] = nums[j];
} else {
goBang[i][j] = add;
}
}
}
}
// 打印棋盘
public void print(){
for (String[] strings : goBang) {
for (String string : strings) {
System.out.print(string);
}
System.out.println();
}
}
// 落子前判断
// 是否超过棋盘
public boolean isOutofQipan(int x, int y) {
if(x>length-1 || x<1 || y>length-1 || y<1){
return true;
}else{
return false;
}
}
// 是否存在棋子
public boolean isExist(int x, int y) {
if(!goBang[x-1][y-1].equals(add)){
return true;
}else{
return false;
}
}
// 落子
public void fall(int x,int y,boolean flag){
goBang[x-1][y-1]=(flag)?"■":"○";
}
// 判断输赢的八个方向
//右
public int right(int xIndex,int yIndex,boolean flag) {
int rightCount=0;
for (int j = yIndex+1; j < goBang.length-1; j++) {
if(goBang[xIndex][j].equals((flag)?"■":"○")){
rightCount++;
continue;
}else{
break;
}
}
return rightCount;
}
//左
public int left(int xIndex,int yIndex,boolean flag) {
int leftCount=0;
for (int j = yIndex-1; j >=0; j--) {
if(goBang[xIndex][j].equals((flag)?"■":"○")){
leftCount++;
continue;
}else{
break;
}
}
return leftCount;
}
//上
public int up(int xIndex,int yIndex,boolean flag) {
int upCount=0;
for (int i = xIndex-1; i >=0; i--) {
if(goBang[i][yIndex].equals((flag)?"■":"○")){
upCount++;
continue;
}else{
break;
}
}
return upCount;
}
//下
public int down(int xIndex,int yIndex,boolean flag) {
int downCount=0;
for (int i = xIndex+1; i <goBang.length-1; i++) {
if(goBang[i][yIndex].equals((flag)?"■":"○")){
downCount++;
continue;
}else{
break;
}
}
return downCount;
}
//右下
public int rightDown(int xIndex,int yIndex,boolean flag) {
int rightDownCount=0;
int i=1;
while(true){
if((xIndex+i)>(goBang.length-1) || (yIndex+i)>(goBang.length-1)){
break;
}
if(goBang[xIndex+i][yIndex+i].equals((flag)?"■":"○")){
rightDownCount++;
i++;
}else{
break;
}
}
return rightDownCount;
}
//左下
public int leftDown(int xIndex,int yIndex,boolean flag) {
int leftDownCount=0;
int i=1;
while(true){
if((xIndex+i)>(goBang.length-1) || (yIndex-i)<0){
break;
}
if(goBang[xIndex+i][yIndex-i].equals((flag)?"■":"○")){
leftDownCount++;
i++;
}else{
break;
}
}
return leftDownCount;
}
//左上
public int leftUp(int xIndex,int yIndex,boolean flag) {
int leftUpCount=0;
int i=1;
while(true){
if((xIndex-i)<0 || (yIndex-i)<0){
break;
}
if(goBang[xIndex-i][yIndex-i].equals((flag)?"■":"○")){
leftUpCount++;
i++;
}else{
break;
}
}
return leftUpCount;
}
//右上
public int rightUp(int xIndex,int yIndex,boolean flag) {
int rightUpCount=0;
int i=1;
while(true){
if((xIndex-i)<0 || (yIndex+i)>(goBang.length-1)){
break;
}
if(goBang[xIndex-i][yIndex+i].equals((flag)?"■":"○")){
rightUpCount++;
i++;
}else{
break;
}
}
return rightUpCount;
}
//判断输赢
public boolean win(int x,int y,boolean flag){
int rightCount=this.right(x-1,y-1,flag);
int leftCount=this.left(x-1,y-1,flag);
int upCount=this.up(x-1,y-1,flag);
int downCount=this.down(x-1,y-1,flag);
int rightDownCount=this.rightDown(x-1,y-1,flag);
int leftDownCount=this.leftDown(x-1,y-1,flag);
int leftUpCount=this.leftUp(x-1,y-1,flag);
int rightUpCount=this.rightUp(x-1,y-1,flag);
// 8个方向组合,变为4个直线方向的连续的棋子长度,装入数组
int[] arr={rightCount+leftCount,upCount+downCount,rightDownCount+leftUpCount,leftDownCount+rightUpCount};
// 求最大长度
Arrays.sort(arr);
if((arr[arr.length-1]+1)>=5){
return true;
}else{
return false;
}
}
}
测试类
package com.dream.goBang;
import java.util.Scanner;
public class GobangTest {
public static void main(String[] args) {
Gobang gobang = new Gobang();
Scanner sc=new Scanner(System.in);
// 交替落子的标志
boolean flag=true;
while(true){
System.out.println(((flag)?"黑":"白")+"子请落子");
int x=sc.nextInt();
int y=sc.nextInt();
if(gobang.isOutofQipan(x, y)){
System.out.println("您输入的坐标超过棋盘范围,请重新输入:");
continue;
}
if (gobang.isExist(x, y)) {
System.out.println("您输入的坐标已有棋子,请重新输入:");
continue;
}
gobang.fall(x, y, flag);
gobang.print();
if(gobang.win(x, y, flag)){
System.out.println(((flag)?"黑":"白")+"子获胜,游戏结束!");
break;
}
flag=!flag;
}
}
}