编程实现控制台版并支持两人对战的五子棋游戏
本人并非科班毕业,毕业之后,在深圳工作了半年,对自己的工作不是很满意,经过一段时间的思考之后,决定学习Java。目前是跟着培训班学习了两周,已经能够独立完成一些简单编程,接下来就主要分享如何编程实现一个简单的两人对战的五子棋游戏以及我在编程过程中遇到的一些问题。
目标:
- 编程实现控制台版并支持两人对战的五子棋游戏
一. 绘制一个15 x 15的棋盘
写一个init方法初始化棋盘,写一个render方法打印棋盘。
//定义变量
package Chess;
import java.util.Scanner;
public class MyChess {
public int[][] chessBoard = new int[16][16];//用二维数组模拟棋盘
public int x;
public int y;//玩家输入下棋坐标(x y)
public boolean isblack = true; //判断哪一方下棋
public static void main(String[] args) {
MyChess chess = new MyChess();
chess.init();
chess.render();
Scanner input = new Scanner(System.in);//引入用户输入
//初始化棋盘
public void init() {
for(int i = 0;i<16;i++) {
for(int j = 0;j<16;j++) {
chessBoard[i][j] = 0;
}
}
}
//打印棋盘
public void render() {
for(int i = 0;i<16;i++) {
for(int j = 0;j<16;j++) {
if(j == 0) {
chessBoard[i][0] = i;
}else if(i == 0) {
chessBoard[0][j] = j;
}
System.out.printf("%-3d",chessBoard[i][j]);
}
System.out.println();
}
}
这里写了一个通过遍历打印棋盘的方法,就可以实现在玩家每次落子之后都能够将其打印出来。
在打印棋盘的时候遇到一个问题:棋盘打印时不能很好的对齐
目标棋盘:
实际打印棋盘:
这里是通过C语言中的System.out.printf()左对齐方法解决了这个问题。
二. 提示黑方(用 1 表示)和白方(用 2 表示)分别下棋(X,Y 轴位置)并重新绘制棋盘。
写一个playChess方法。
//下棋
public void playChess(Scanner input) {
//玩家输入坐标
if(isblack) { //选择黑方优先落子
System.out.println("黑方回合:");
}else {
System.out.println("白方回合:");
}
x = input.nextInt();
y = input.nextInt(); //用于接收用户输入的坐标,用空格隔开
//判断输入是否合法
if(x>0&&x<16&&y>0&&y<16) {
//判断当前位置是否已有棋子
if(chessBoard[x][y] !=0) {
System.out.println("当前位置已有棋子,请重新输入!");
playChess(input); // 如果已有棋子,则重新运行playChess方法
}
if(isblack) {
chessBoard[x][y] = 1; //是黑子则输入1
}else {
chessBoard[x][y] = 2; //是白子则输入2
}
//交换 经过一次落子之后,交换下棋方
isblack = !isblack;
}else {
System.out.println("请输入正确的坐标!");
playChess(input);
}
}
这里需要注意的是用布尔型变量isblack去判断是黑方还是白方,我一开始的时候就没想到这一点,用
x = input.nextInt();y = input.nextInt(); 连续接收两次用户输入,这样就会造成每当一方下完棋之后,就会提示另一方下棋,用isblack变量判断就可以避免出现这种情况,当一方胜利时,就终止游戏。
三. 每当一方下棋后判断是否获胜 。
这里我们要考虑四种胜利条件
- 竖直 | 方向五子连珠
- 水平 — 方向五子连珠
- 左斜 \ 方向五子连珠
- 右斜 / 方向五子连珠
写一个check方法,创建count变量用于计数,遍历当前落子位置四周相同棋子数量
//判断输赢
public boolean check() {
int count = 1;
int currentCheck = chessBoard[x][y]; //记录当前位置的值
//遍历上下
//遍历上方
//判断相邻的棋子是否相同,如果相同, 则count+1,并继续判断下一个位置的棋子是否相同,
如果不相同,则结束。
for(int i = x-1;i>0;i--) {
if(chessBoard[i][y] == currentCheck) {
count++;
}else {
break;
}
}
//遍历下方
for(int i = x+1;i<16;i++) {
if(chessBoard[i][y] == currentCheck) {
count++;
}else {
break;
}
}
System.out.println("当前棋子竖直方向:"+count);
if(count >= 5) {
return true;
}else {
count = 1;
}
//遍历左右
//遍历左
for(int i = y-1;i>0;i--) {
if(chessBoard[x][i] == currentCheck) {
count++;
}else {
break;
}
}
//遍历右
for(int i = y+1;i<16;i--) {
if(chessBoard[x][i] == currentCheck) {
count++;
}else {
break;
}
}
System.out.println("当前棋子水平方向:"+count);
if(count >= 5) {
return true;
}else {
count = 1;
}
//遍历\方向
//左上
for(int i = x-1,j = y-1;i>0&&j>0;i--,j--) {
if(chessBoard[i][j] == currentCheck) {
count++;
}else {
break;
}
}
//右下
for(int i = x+1,j = y+1;i<16&&j<16;i++,j++) {
if(chessBoard[i][j] == currentCheck) {
count++;
}else {
break;
}
}
System.out.println("当前棋子 \\ 方向:"+count);
if(count >= 5) {
return true;
}else {
count = 1;
}
//遍历/方向
//左下
for(int i = x+1,j = y-1;i<16&&j>0;i++,j--) {
if(chessBoard[i][j] == currentCheck) {
count++;
}else {
break;
}
}
//右上
for(int i = x-1,j = y+1;i>0&&j<16;i--,j++) {
if(chessBoard[i][j] == currentCheck) {
count++;
}else {
break;
}
}
System.out.println("当前棋子 / 方向:"+count);
if(count >= 5) {
return true;
}else {
count = 1;
}
return false;
}
四.创建while死循环
while(true) {
//下棋
System.out.println("请输入坐标(用空格隔开):");
chess.playChess(input);
//刷新棋盘
chess.render();
//判断输赢
if(chess.check()) {
if(chess.isblack) {
System.out.println("白方胜利");
}else {
System.out.println("黑方胜利");
}
break;
}
}
总结:在思考过程中,要将打印棋盘、提示玩家下棋、判断输赢各部分都单独作为一个问题去思考,每一部分都创建一个独立的方法,在使用时,调用方法就可以了。