题目:使用二维数组实现五子棋功能
要求:1.使用二维数组储存五子棋棋盘
2.在控制台通过Scanner输入黑白棋坐标
分析:1.在开始下棋前要初始化棋盘,并输出
2.让黑白双方进行交替下棋
3.在每次落子时判断该棋子有没有越界或是重复落子
4.每次下完后打印此状态下的棋盘
5.判断双方输赢
求解:
在这里先给出一个负责运行功能的.java文件
public class WZQrun {
public static void main(String[] args) {
WZQ.start();
}
}
这里给出一个,能够实现功能,但效率不高的代码 如下:
import java.util.Scanner;
public class WZQ {
static String white = "☆";
static String black = "★";
static String[][] qp = new String[15][15];//棋盘
static String[] num = {"⒈", "⒉", "⒊", "⒋", "⒌", "⒍", "⒎", "⒏", "⒐", "⒑", "⒒", "⒓", "⒔", "⒕", "⒖"};
static String line = "十";
static boolean flag = true;
/**
* 启动五子棋游戏
*/
public static void start() {
init();
print();
// 交替下棋
for (; ; ) {
whoDown();
// 列输入
System.out.print("x = ");
int cell = positionIn();
// 行输入
System.out.print("y = ");
int row = positionIn();
// 下棋
down(row, cell);
// 显示结果
print();
//输赢判断
if (judgement()) {
System.out.println("游戏结束!");
break;
}
if (judgement(row,cell)) {
System.out.println("游戏结束!");
break;
}
}
}
/**
* 棋盘初始化
*/
public static void init() {
for (int i = 0; i < qp.length; i++) {
if (i == qp.length - 1) {
for (int k = 0; k < qp[i].length; k++) {
qp[i][k] = num[k];
}
} else {
for (int j = 0; j < qp[i].length; j++) {
if (i <= qp[i].length - 2) {
qp[i][j] = line;
}
if (j == qp[i].length - 1) {
qp[i][j] = num[i];
}
}
}
}
}
/**
* 打印棋盘
*/
public static void print() {
for (int i = 0; i < qp.length; i++) {
for (int j = 0; j < qp[i].length; j++) {
System.out.print(qp[i][j] + " ");
}
System.out.println();
}
}
/**
* 判断是否能在棋盘上下棋并执行
*
* @param row 行位置
* @param cell 列位置
*/
public static void down(int row, int cell) {
if ((row >= qp.length - 1 || row < 0) || (cell >= qp.length || cell < 0)) {
System.out.println("超出棋盘范围,请重新落子!");
return;
}
if (qp[row][cell].equals(line)) {
if (flag) {
qp[row][cell] = black;
flag = false;
} else {
qp[row][cell] = white;
flag = true;
}
} else {
System.out.println("此处已有棋,请重新落子!");
}
}
/**
* 判断下棋方
*/
public static void whoDown() {
// 黑先白后
if (flag) {
System.out.println("黑方落子位置坐标(x,y)");
} else {
System.out.println("白方落子位置坐标(x,y)");
}
}
/**
* 行/列的输入
*/
public static int positionIn() {
Scanner temp1 = new Scanner(System.in);
return temp1.nextInt() - 1;
}
/**
* 输赢判断
*/
public static boolean judgement() {
boolean whiteWin = false, blackWin = false;
// 横判断
for (int i = 0; i < qp.length - 1; i++) {
for (int j = 0; j < qp[i].length - 5; j++) {
if (qp[i][j].equals(black) && qp[i][j + 1].equals(black) && qp[i][j + 2].equals(black) && qp[i][j + 3].equals(black) && qp[i][j + 4].equals(black)) {
blackWin = true;
break;
}
if (qp[i][j].equals(white) && qp[i][j + 1].equals(white) && qp[i][j + 2].equals(white) && qp[i][j + 3].equals(white) && qp[i][j + 4].equals(white)) {
whiteWin = true;
break;
}
}
}
// 竖判断
if (!blackWin && !whiteWin) {
for (int i = 0; i < qp.length - 5; i++) {
for (int j = 0; j < qp[i].length - 1; j++) {
if (qp[i][j].equals(black) && qp[i + 1][j].equals(black) && qp[i + 2][j].equals(black) && qp[i + 3][j].equals(black) && qp[i + 4][j].equals(black)) {
blackWin = true;
break;
}
if (qp[i][j].equals(white) && qp[i + 1][j].equals(white) && qp[i + 2][j].equals(white) && qp[i + 3][j].equals(white) && qp[i + 4][j].equals(white)) {
whiteWin = true;
break;
}
}
}
}
// 左斜判断
if (!blackWin && !whiteWin) {
for (int i = 0; i < qp.length - 5; i++) {
for (int j = 4; j < qp.length - 1; j++) {
if (qp[i][j].equals(black) && qp[i + 1][j - 1].equals(black) && qp[i + 2][j - 2].equals(black) && qp[i + 3][j - 3].equals(black) && qp[i + 4][j - 4].equals(black)) {
blackWin = true;
break;
}
if (qp[i][j].equals(white) && qp[i + 1][j - 1].equals(white) && qp[i + 2][j - 2].equals(white) && qp[i + 3][j - 3].equals(white) && qp[i + 4][j - 4].equals(white)) {
whiteWin = true;
break;
}
}
}
}
// 右斜判断
if (!blackWin && !whiteWin) {
for (int i = 0; i < qp.length - 5; i++) {
for (int j = 0; j < qp.length - 5; j++) {
if (qp[i][j].equals(black) && qp[i + 1][j + 1].equals(black) && qp[i + 2][j + 2].equals(black) && qp[i + 3][j + 3].equals(black) && qp[i + 4][j + 4].equals(black)) {
blackWin = true;
break;
}
if (qp[i][j].equals(white) && qp[i + 1][j + 1].equals(white) && qp[i + 2][j + 2].equals(white) && qp[i + 3][j + 3].equals(white) && qp[i + 4][j + 4].equals(white)) {
whiteWin = true;
break;
}
}
}
}
if (whiteWin) {
System.out.println("恭喜白棋获得胜利");
return true;
}
if (blackWin) {
System.out.println("恭喜黑棋获得胜利");
return true;
}
return false;
}
}
思考:
从上面的代码中得到对于输赢判断的逻辑思维:在每次交替下棋后都需要对这个棋盘(二维数组)的每一个元素进行遍历,知道找出符合要求的情况。
优化思路:
那么每次交替下棋过后,只有一处位置的元素发生了改变,并不是所有的元素都发生了变化,那么每次对数组的遍历就会显得非常的多余。因此我们只需要换一种思路:在每次交替下棋过后,我们只需要判断落子位置处的横竖斜这几个方向上,有没有与其相邻的五颗相同棋子(包括落子的那颗),如果满足了要求,就可以输出结果了。
优化后(只对部分方法的代码进行了更改):
/**
* 启动五子棋游戏(优化后)
*/
public static void start() {
init();
print();
// 交替下棋
for (; ; ) {
whoDown();
// 列输入
System.out.print("x = ");
int cell = positionIn();
// 行输入
System.out.print("y = ");
int row = positionIn();
// 下棋
if(!down(row, cell)){
print();
continue;
}
print();
// 输赢判断
if (judgement(row, cell)) {
System.out.println("游戏结束!");
break;
}
}
}
/**
* 判断是否能在棋盘上下棋并执行(优化后)
*
* @param row 行位置
* @param cell 列位置
*/
public static boolean down(int row, int cell) {
if ((row >= qp.length - 1 || row < 0) || (cell >= qp.length || cell < 0)) {
System.out.println("超出棋盘范围,请重新落子!");
return false;
}
if (qp[row][cell].equals(line)) {
if (flag) {
qp[row][cell] = black;
flag = false;
} else {
qp[row][cell] = white;
flag = true;
}
return true;
} else {
System.out.println("此处已有棋,请重新落子!");
return false;
}
}
/**
* 输赢判断
*/
public static boolean judgement(int row, int cell) {
//
int timesRow = 1, timesCell = 1, timesLeft = 1, timesRight = 1;
boolean flagTurn = true;
String temp = black;
if (flag) {
temp = white;
}
for (int i = 0; i < 5; i++) {
if (cell + i < qp.length && qp[row][cell + i].equals(temp) && flagTurn) {
timesRow++;
} else {
flagTurn = false;
}
if (cell - i >= 0 && qp[row][cell - i].equals(temp) && !flagTurn) {
timesRow++;
}else{
flagTurn = true;
}
}
for (int i = 0; i < 5; i++) {
if (row + i < qp.length && qp[row + i][cell].equals(temp) && flagTurn) {
timesCell++;
} else {
flagTurn = false;
}
if (row - i >= 0 && qp[row - i][cell].equals(temp) && !flagTurn) {
timesCell++;
}
else{
flagTurn = true;
}
}
for (int i = 0; i < 5; i++) {
if (row - i >= 0 && cell + i < qp.length && qp[row - i][cell + i].equals(temp) && flagTurn) {
timesLeft++;
} else {
flagTurn = false;
}
if (row + i < qp.length && cell - i >= 0 && qp[row + i][cell - i].equals(temp) && !flagTurn) {
timesLeft++;
}
else{
flagTurn = true;
}
}
for (int i = 0; i < 5; i++) {
if (row + i < qp.length && cell + i < qp.length && qp[row + i][cell + i].equals(temp) && flagTurn) {
timesRight++;
} else {
flagTurn = false;
}
if (row - i >= 0 && cell - i >= 0 && qp[row - i][cell - i].equals(temp) && !flagTurn) {
timesRight++;
}
else{
flagTurn = true;
}
}
if (timesRow > 5 || timesCell > 5 || timesLeft > 5 || timesRight > 5) {
if(!flag){
System.out.println("恭喜黑棋获得胜利");
}
else{
System.out.println("恭喜白棋获得胜利");
}
return true;
}
return false;
}
交互结果展示: