编程实现控制台版并支持两人对战的五子棋游戏。
(1)绘制棋盘 - 写一个成员方法实现
(2)提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。
(3)每当一方下棋后判断是否获胜 - 写一个成员方法实现。
(4)提示: 采用二维数组来模拟并描述棋盘,棋盘如下:
1. 绘制棋盘 - 写一个成员方法实现
private int[][] gobang = new int[16][16];
public void draw(){
for (int i = 0; i < gobang.length+1; i++) {
if (0 == i ) {
System.out.print(" ");
} else if (i <= 10 ) {
System.out.print((char)(i - 1 + '0')+" ");
} else {
System.out.print((char)(i - 11 + 'a')+" ");
}
}
System.out.println();
for (int i = 0; i < gobang.length; i++) {
if (i < 10 ) {
System.out.print((char)(i + '0')+" ");
} else {
System.out.print((char)(i - 9 + 'a')+" ");
}
for (int j = 0; j < gobang[i].length; j++) {
if(0 == gobang[i][j]){
System.out.print("+ ");
} else if(1 == gobang[i][j]){
System.out.print("@ ");
} else {
System.out.print("O ");
}
}
System.out.println();
}
}
2.输入下棋坐标
public void play(){
Scanner sc = new Scanner(System.in);
while(true){
draw();
if (flag) {
System.out.println("------------------------黑子------------------------");
} else {
System.out.println("------------------------白子------------------------");
}
System.out.println("请输入您要落子的行位置和列位置(如: 0 4):");
int x = sc.nextInt();
int y = sc.nextInt();
if (islegitimate(x,y)){//判断是否合法,合法继续操作,不合法结束
playChess(x, y);//修改棋盘数据,达到下棋效果
if(isWin(x,y)){//判断是否输赢
break;
}
flag = !flag;
}
}
}
3.判断是否合法
/**
* 判断是否合法,合法继续操作,不合法结束
* @param x 横坐标
* @param y 纵坐标
* @return
*/
public boolean islegitimate(int x,int y){
if(x < 0 || x > 16 || y < 0 || y > 16){
System.err.println("您落子落到棋盘外面去了,请重新落子!!");
return false;
}else {
if(gobang[x][y] != 0){
System.err.println("您落子的位置已有棋子,请重新落子!!");
return false;
} else {
return true;
}
}
}
4.修改棋盘(下棋)
/**
* 修改棋盘数据,达到下棋效果
* @param x 横坐标
* @param y 纵坐标
*/
public void playChess(int x,int y){
if (flag) {
gobang[x][y] = 1;
} else {
gobang[x][y] = 2;
}
}
5.判断是否获胜
/**
* 判断是否获胜
* @param x 横坐标
* @param y 纵坐标
* @return true表示获胜,false继续下棋
*/
public boolean isWin(int x, int y){
int highBound = gobang.length;
int lowBound = 0;
int[] line = new int[9];
int[] column = new int[9];
int[] leftDiagonal = new int[9];
int[] rightDiagonal = new int[9];
column[4] = line[4] = leftDiagonal[4] = rightDiagonal[4] = gobang[x][y];
for (int i = 1; i <= 4; i++) {
// 生成横方向的成线情况
if (y - i >= lowBound) {
line[4 - i] = gobang[x][y - i];
}
if (y + i <= highBound) {
line[4 + i] = gobang[x][y + i];
}
// 生成纵方向的成线情况
if (x - i >= lowBound) {
column[4 - i] = gobang[x - i][y];
}
if (x + i <= highBound) {
column[4 + i] = gobang[x + i][y];
}
// 生成左斜方向上的成线情况
if (x - i >= lowBound && y - i >= lowBound) {
leftDiagonal[4 + i] = gobang[x - i][y - i];
}
if (x + i <= highBound && y + i <= highBound) {
leftDiagonal[4 - i] = gobang[x + i][y + i];
}
// 生成右斜方向上的成线情况
if (x - i >= lowBound && y + i <= highBound) {
rightDiagonal[4 + i] = gobang[x - i][y + i];
}
if (y - i >= lowBound && x + i <= highBound) {
rightDiagonal[4 - i] = gobang[x + i][y - i];
}
}
// 判断4个方向是否存在五子连珠的情况
boolean resline = fiveSons(line, x, y);
boolean rescolumn = fiveSons(column, x, y);
boolean resLeftDiagonal = fiveSons(leftDiagonal, x, y);
boolean resRightDiagonal = fiveSons(rightDiagonal, x, y);
// 若有一个方向上的存在五子连珠的情况,则胜利
if(resline || rescolumn || resLeftDiagonal || resRightDiagonal) {
if(flag){
System.out.println("黑子获胜");
}else {
System.out.println("白子获胜");
}
draw();
return true;
}else {
return false;
}
}
下面是完整代码
Gobang类
package cn.cyh.test;
import java.util.Scanner;
/**
* @author cyh
* @create 2020/12/21 10:20
*/
public class Gobang {
//
private int[][] gobang = new int[16][16];
private boolean flag = true;
private static Gobang gob = new Gobang();
//单例
private Gobang() { }
public static Gobang getGobang(){
return gob;
}
/**
* 绘画棋盘
*/
public void draw(){
for (int i = 0; i < gobang.length+1; i++) {
if (0 == i ) {
System.out.print(" ");
} else if (i <= 10 ) {
System.out.print((char)(i - 1 + '0')+" ");
} else {
System.out.print((char)(i - 11 + 'a')+" ");
}
}
System.out.println();
for (int i = 0; i < gobang.length; i++) {
if (i < 10 ) {
System.out.print((char)(i + '0')+" ");
} else {
System.out.print((char)(i - 9 + 'a')+" ");
}
for (int j = 0; j < gobang[i].length; j++) {
if(0 == gobang[i][j]){
System.out.print("+ ");
} else if(1 == gobang[i][j]){
System.out.print("@ ");
} else {
System.out.print("O ");
}
}
System.out.println();
}
}
/**
* 下棋
* @param x 横坐标
* @param y 纵坐标
*/
public void playChess(int x,int y){
if (flag) {
gobang[x][y] = 1;
} else {
gobang[x][y] = 2;
}
}
/**
* 判断是否获胜
* @param x 横坐标
* @param y 纵坐标
* @return true表示获胜,false继续下棋
*/
public boolean isWin(int x, int y){
int highBound = gobang.length;
int lowBound = 0;
int[] line = new int[9];
int[] column = new int[9];
int[] leftDiagonal = new int[9];
int[] rightDiagonal = new int[9];
column[4] = line[4] = leftDiagonal[4] = rightDiagonal[4] = gobang[x][y];
for (int i = 1; i <= 4; i++) {
// 生成横方向的成线情况
if (y - i >= lowBound) {
line[4 - i] = gobang[x][y - i];
}
if (y + i <= highBound) {
line[4 + i] = gobang[x][y + i];
}
// 生成纵方向的成线情况
if (x - i >= lowBound) {
column[4 - i] = gobang[x - i][y];
}
if (x + i <= highBound) {
column[4 + i] = gobang[x + i][y];
}
// 生成左斜方向上的成线情况
if (x - i >= lowBound && y - i >= lowBound) {
leftDiagonal[4 + i] = gobang[x - i][y - i];
}
if (x + i <= highBound && y + i <= highBound) {
leftDiagonal[4 - i] = gobang[x + i][y + i];
}
// 生成右斜方向上的成线情况
if (x - i >= lowBound && y + i <= highBound) {
rightDiagonal[4 + i] = gobang[x - i][y + i];
}
if (y - i >= lowBound && x + i <= highBound) {
rightDiagonal[4 - i] = gobang[x + i][y - i];
}
}
// 判断4个方向是否存在五子连珠的情况
boolean resline = fiveSons(line, x, y);
boolean rescolumn = fiveSons(column, x, y);
boolean resLeftDiagonal = fiveSons(leftDiagonal, x, y);
boolean resRightDiagonal = fiveSons(rightDiagonal, x, y);
// 若有一个方向上的存在五子连珠的情况,则胜利
if(resline || rescolumn || resLeftDiagonal || resRightDiagonal) {
if(flag){
System.out.println("黑子获胜");
}else {
System.out.println("白子获胜");
}
draw();
return true;
}else {
return false;
}
}
/**
* 以x和y为中心,判断多少个相同的棋子
* @param arr 获取到长度为9,中心是xy的数组
* @param x 横坐标
* @param y 纵坐标
* @return true表示以x为中心的数组有5个,游戏结束
*/
private boolean fiveSons(int[] arr, int x, int y) {
int count = 1; // 统计连续子的个数
for(int i = 0; i < 5;) {
if (arr[i] == gobang[x][y]) {
for (int j = i + 1; j < 9; j++) {
if(arr[j] == arr[j - 1]) {
count += 1;
if(5 == count) {
return true; // 若找到五子连珠的情况,则返回胜利标示符true
}
}else {
count = 1;
i = j;
break;
}
}
}
i++;
}
return false;
}
public boolean islegitimate(int x,int y){
if(x < 0 || x > 16 || y < 0 || y > 16){
System.err.println("您落子落到棋盘外面去了,请重新落子!!");
return false;
}else {
if(gobang[x][y] != 0){
System.err.println("您落子的位置已有棋子,请重新落子!!");
return false;
} else {
return true;
}
}
}
public void play(){
Scanner sc = new Scanner(System.in);
while(true){
draw();
if (flag) {
System.out.println("------------------------黑子------------------------");
} else {
System.out.println("------------------------白子------------------------");
}
System.out.println("请输入您要落子的行位置和列位置(如: 0 4):");
int x = sc.nextInt();
int y = sc.nextInt();
if (islegitimate(x,y)){
playChess(x, y);
if(isWin(x,y)){
break;
}
flag = !flag;
}
}
}
}
GobangTest 测试类
package cn.cyh.test;
/**
* 五子棋测试类
* @author cyh
* @create 2020/12/21 14:42
*/
public class GobangTest {
public static void main(String[] args) {
Gobang gobang = new Gobang();
gobang.play();
}
}