JAVA练习之五子棋(二维数组)

题目:

五子棋任务是选修任务,不是必须完成的任务。
五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类
游戏。通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,
先形成五子连线者获胜。
 

我的思路:

1、需要创建一个16*16的棋盘,第一行和第一列标上序号

2、让用户输入位置,使用一个数组来保存这个位置

3、在用户输入之后立即更新屏幕并输出。

4、判断是否五子成线。在这个问题上我纠结了一整天,不知道怎么去处理数组的边界问题,最后还是借鉴了大佬的判定算法,地址:https://blog.csdn.net/qq_28051453/article/details/51843130?tdsourcetag=s_pctim_aiomsg主要是采用三位数组来存储行列和斜行。

 

代码实现:

1、构造棋盘:

// 棋盘
public static int[][] QiPan() {
	int[][] arr = new int[16][16];
	try {

		for (int i = 0; i < arr.length; i++) {
			arr[0][i] = i;
			arr[i][0] = i;
		}

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
			    System.out.printf("%-4d", arr[i][j]);
			}
			System.out.println();
			}
		} catch (Exception e) {
		    System.out.println("游戏异常退出!");
		}

    return arr;
}

2、获取用户输入:

// 用户1输入位置
	public static int[] Pos1() {
		int[] pos1 = new int[2];
		Scanner input = new Scanner(System.in);
		System.out.println("黑方请输入你落棋在第几行::");
		pos1[0] = input.nextInt();
		System.out.println("黑方请输入你落棋在第几列:");
		pos1[1] = input.nextInt();

		return pos1;
	}

	// 用户2输入位置
	public static int[] Pos2() {
		int[] pos2 = new int[2];
		Scanner input = new Scanner(System.in);
		System.out.println("白方请输入你落棋在第几行::");
		pos2[0] = input.nextInt() ;
		System.out.println("白方请输入你落棋在第几列:");
		pos2[1] = input.nextInt() ;

		return pos2;
	}

3、更新屏幕

// 更新用户1棋盘
	public static int[][] Update1(int[][] arr, int[] pos) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (i == pos[0] && j == pos[1]) {
					arr[i][j] = 1;
				}
			}
		}
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				System.out.printf("%-4d", arr[i][j]);
			}
			System.out.println();
		}

		return arr;
	}

	// 更新用户2棋盘
	public static int[][] Update2(int[][] arr, int[] pos) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (pos[0] == i && pos[1] == j) {
					arr[i][j] = 2;
					break;
				}
			}
		}

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				System.out.printf("%-4d", arr[i][j]);
			}
			System.out.println();
		}
		return arr;
	}

4、判断胜负:

// 判断是否获胜
	public static boolean CheckWin(int xIndex, int yIndex, int[][] arr) {
		int max = 0;
		int tempXIndex = xIndex;
		int tempYIndex = yIndex;
		boolean flag;
		// 三维数组记录横向,纵向,左斜,右斜的移动
		int[][][] dir = new int[][][] {
				// 横向
				{ { -1, 0 }, { 1, 0 } },
				// 竖着
				{ { 0, -1 }, { 0, 1 } },
				// 左斜
				{ { -1, -1 }, { 1, 1 } },
				// 右斜
				{ { 1, -1 }, { -1, 1 } } };

		for (int i = 0; i < 4; i++) {
			int count = 1;
			// j为0,1分别为棋子的两边方向,比如对于横向的时候,j=0,表示下棋位子的左边,j=1的时候表示右边
			for (int j = 0; j < 2; j++) {
				flag = true;
				/**
				 * while语句中为一直向某一个方向遍历 有相同颜色的棋子的时候,Count++ 否则置flag为false,结束该该方向的遍历
				 **/
				while (flag) {
					tempXIndex = tempXIndex + dir[i][j][0];
					tempYIndex = tempYIndex + dir[i][j][1];

					// 这里加上棋盘大小的判断,这里我设置的棋盘大小为20 具体可根据实际情况设置 防止越界
					if (tempXIndex >= 0 && tempXIndex <= 15 && tempYIndex >= 0 && tempYIndex <= 15) {
						if ((arr[tempXIndex][tempYIndex] == arr[xIndex][yIndex])) {
							count++;
							System.out.println(count);
						} else
							flag = false;
					} else {
						flag = false;
					}

				}
				tempXIndex = xIndex;
				tempYIndex = yIndex;
			}

			if (count >= 5) {
				max = 1;
				break;
			} else
				max = 0;
		}
		if (max == 1)
			return true;
		else
			return false;
	}

5、总程序:

package day04;

import java.util.Scanner;

public class day04 {
	public static void main(String[] args) {

		// 棋盘
		int[][] arr = new int[16][16];
		arr = QiPan();
		int[] pos1 = new int[2];
		int[] pos2 = new int[2];
		int count = 0;
		boolean bool = false;
		while (true) {
				pos1 = Pos1();
				int x1 = pos1[0];
				int y1 = pos1[1];
				arr = Update1(arr, pos1);
				bool = CheckWin(x1, y1, arr);
				if (bool == true) {
						System.out.println("游戏结束,黑方胜。");
						break;
					}
			
			
				pos2 = Pos2();
				int x2 = pos2[0];
				int y2 = pos2[1];
				arr = Update2(arr, pos2);
				bool = CheckWin(x2, y2, arr);
				if (bool == true) {
						System.out.println("游戏结束,白方胜。");
						break;
					}

	}

	}

	// 棋盘
	public static int[][] QiPan() {
		int[][] arr = new int[16][16];
		try {

			for (int i = 0; i < arr.length; i++) {
				arr[0][i] = i;
				arr[i][0] = i;
			}

			for (int i = 0; i < arr.length; i++) {
				for (int j = 0; j < arr[i].length; j++) {
					System.out.printf("%-4d", arr[i][j]);

				}
				System.out.println();
			}
		} catch (Exception e) {
			System.out.println("游戏异常退出!");
		}

		return arr;

	}

	// 用户1输入位置
	public static int[] Pos1() {
		int[] pos1 = new int[2];
		Scanner input = new Scanner(System.in);
		System.out.println("黑方请输入你落棋在第几行::");
		pos1[0] = input.nextInt();
		System.out.println("黑方请输入你落棋在第几列:");
		pos1[1] = input.nextInt();

		return pos1;
	}

	// 用户2输入位置
	public static int[] Pos2() {
		int[] pos2 = new int[2];
		Scanner input = new Scanner(System.in);
		System.out.println("白方请输入你落棋在第几行::");
		pos2[0] = input.nextInt() ;
		System.out.println("白方请输入你落棋在第几列:");
		pos2[1] = input.nextInt() ;

		return pos2;
	}

	// 更新用户1棋盘
	public static int[][] Update1(int[][] arr, int[] pos) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (i == pos[0] && j == pos[1]) {
					arr[i][j] = 1;
				}
			}
		}
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				System.out.printf("%-4d", arr[i][j]);
			}
			System.out.println();
		}

		return arr;
	}

	// 更新用户2棋盘
	public static int[][] Update2(int[][] arr, int[] pos) {
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (pos[0] == i && pos[1] == j) {
					arr[i][j] = 2;
					break;
				}
			}
		}

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				System.out.printf("%-4d", arr[i][j]);
			}
			System.out.println();
		}
		return arr;
	}

	// 判断是否获胜
	public static boolean CheckWin(int xIndex, int yIndex, int[][] arr) {
		int max = 0;
		int tempXIndex = xIndex;
		int tempYIndex = yIndex;
		boolean flag;
		// 三维数组记录横向,纵向,左斜,右斜的移动
		int[][][] dir = new int[][][] {
				// 横向
				{ { -1, 0 }, { 1, 0 } },
				// 竖着
				{ { 0, -1 }, { 0, 1 } },
				// 左斜
				{ { -1, -1 }, { 1, 1 } },
				// 右斜
				{ { 1, -1 }, { -1, 1 } } };

		for (int i = 0; i < 4; i++) {
			int count = 1;
			// j为0,1分别为棋子的两边方向,比如对于横向的时候,j=0,表示下棋位子的左边,j=1的时候表示右边
			for (int j = 0; j < 2; j++) {
				flag = true;
				/**
				 * while语句中为一直向某一个方向遍历 有相同颜色的棋子的时候,Count++ 否则置flag为false,结束该该方向的遍历
				 **/
				while (flag) {
					tempXIndex = tempXIndex + dir[i][j][0];
					tempYIndex = tempYIndex + dir[i][j][1];

					// 这里加上棋盘大小的判断,这里我设置的棋盘大小为20 具体可根据实际情况设置 防止越界
					if (tempXIndex >= 0 && tempXIndex <= 15 && tempYIndex >= 0 && tempYIndex <= 15) {
						if ((arr[tempXIndex][tempYIndex] == arr[xIndex][yIndex])) {
							count++;
							System.out.println(count);
						} else
							flag = false;
					} else {
						flag = false;
					}

				}
				tempXIndex = xIndex;
				tempYIndex = yIndex;
			}

			if (count >= 5) {
				max = 1;
				break;
			} else
				max = 0;
		}
		if (max == 1)
			return true;
		else
			return false;
	}
}

注意:打印棋盘是用:System.out.printf("%-4d", arr[i][j]);可以是棋盘更规整,另外中间的数字4是可以更改的。

才学习Java,如果写的程序有错误的地方请大家多多指教,欢迎大家来一起交流沟通。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值