肥桃Java学习记录7:简易五子棋

编写一个简易的五子棋

  1. 要求

在这里插入图片描述

  1. 绘制棋盘 3
  2. 提示黑方(用 1 表示)和白方(用 2 表示)分别下棋(X,Y 轴位置) 并重新绘制棋盘。
  3. 每当一方下棋后判断是否获胜 。

由于代码多了看起来比较麻烦,这里选择写在多个方法里。
主体部分
思路是使用空的二维数组作为棋盘,然后给棋盘赋值网格线作为基础,打印棋盘让用户进行选择。之后接收用户的输入,并且每次落子都顺带判断胜负。

import java.util.Scanner;
public class WuZiQi {
	//空棋盘
	private static int[][] board = new int[16][16]; 

	
	public static void main(String[] args) {
    //设定棋盘 初始化 边界序号 打印棋盘
	markBoard();			
	initBoard();	
	printBoard();
	//接受用户输入
	startGame();
	}

方法startGame()
先获取落子信息,如果输入值为null说明落子位置有误,重新等待输入。
之后调用setChess()方法,来转换棋权,同时打印新落子后的棋盘。
每次落子都需要调用win()方法来判断是否胜利。

	//开始游戏
    private static void startGame(){
    	//创建循环来处理用户落子
    	while(true) {
    		Chessman chessman = getUserInput();
    		if(chessman == null) {
    			continue;
    		}
    		//落子之后重新打印棋盘
    		setChess(chessman);
    		printBoard();
    		
    		if(win(chessman)) {
    			System.out.println("胜利");
    			return;
    		}
    	}
    }

方法markBoard()
这个方法用于给空的二维数组赋值,来创建边界序号。

	//边界序号
    private static void markBoard() {
    	int m = 0;
    	for(int i = 0; i < board.length; i++) {
    		m = i;
    		for(int j = 0; j < board[i].length; j++) {
    		board[i][j] = m;
    		m++;
    		}
    	}
    }

方法printBoard()

  //打印棋盘
    private static void printBoard() {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                System.out.print(board[i][j]+"\t");
            }
            System.out.println();
        }
    }

方法initBoard()
初始化棋盘,将除了边界序号的部分都赋值为0.

    //初始化棋盘
    private static void initBoard() {
        for (int i = 1; i < board.length; i++) {
            for (int j = 1; j < board[i].length; j++) {
                board[i][j] = 0;
            }
        }
    }

方法setChess()
声明一个布尔类型的变量,通过true/false来判断是该谁下棋。每落子一次true/false值互换。

    //落子 判断该谁落子
    private static boolean firstMan = true;
    private static void setChess( Chessman chessman) {
    	if(firstMan) {
    		board[chessman.x][chessman.y] = 1;
    	}else {
    		board[chessman.x][chessman.y] = 2;
    	}
    	firstMan = !firstMan;
    }

方法getUserInput()
起初思考让用户单独输入横纵坐标,但是操作起来用户非常麻烦。所以想着使用一个string类型的数组来储存输入,长度为2,让用户输入x,y,再由split删除“,”即可,分出的两个字符串刚好放入数组中。
之后还需要对落子位置进行判断,如果在不为0的地方落子则会提示已经有棋子了。

    //获取落子的位置
    private static Chessman getUserInput() {
    	int setMan;
    	if(firstMan) {
    		setMan = 1;
    	}else {
    		setMan = 2;
    	}
    	Scanner scanner = new Scanner(System.in);
    	System.out.println("请" + setMan + "玩家落子");
    	String text = scanner.next();
    	String[] texts = text.split(",");
    	int a = -1;
    	int b = -1;
    	a = Integer.valueOf(texts[0]);
    	b = Integer.valueOf(texts[1]);
    	//如果用户输入的数值超出棋盘范围,则返回值为null
    	if(a < 0 || a > board.length) {
    		System.out.println("输入错误 请重新输入");
    		return null;
    	}
    	if(b < 0 || b > board.length) {
    		System.out.println("输入错误 请重新输入");
    		return null;
    	}
    	if(0 != board[a][b]) {
    		System.out.println("此处已经有棋子了");
    		return null;
    	}
    	return new Chessman(a,b);
    }

方法win()
每次落子都需要进行是否胜利的判断。可以用遍历棋子所在的横 纵 斜 反斜 四个方向上的值来判断是否有连续的五子。横纵方向的判断非常好理解,只需要控制X或Y不变进行遍历即可,斜向卡壳了很久,因为在xy都有变化时总是会出现超出边界的问题。后来通过增加了if_continue语句来忽略超出边界的部分从而解决了问题。另外在思考斜线时使用的是斜率的思考方法,但是总感觉有所欠缺,需多多练习。

    //获胜判断
    private static boolean win( Chessman chessman) {
    	int count = 0;
    	//横向
    	for(int c = 1; c < board.length; c++) {
    		//如果横坐标和k值相等 则连子数加一
    		if(board[chessman.x][c] == board[chessman.x][chessman.y]) {
    			count++;
    		}else {
    			count = 0;
    		}
    		if(count == 5) {
    			return true;
    		}
    	}
    	//纵向
    	for(int c =1; c < board.length; c++) {
    		if(board[c][chessman.y] == board[chessman.x][chessman.y]) {
    			count++;
    		}else {
    			count = 0;
    		}
    		if(count == 5) {
    			return true;
    		}
    	}
    	//斜向下 
        int z1 =chessman.x - chessman.y;
        //System.out.println("零点是" + z1);
        for (int k = 0; k < board.length; z1++, k++) {

            if (z1 >= board.length || z1 < 0) {
                continue;
            }
            if (board[z1][k] ==(board[chessman.x][chessman.y])) {
                count++;
            } else {
                count = 0;
            }
            if (count == 5) {
                return true;
            }
        }
    	//斜向上
        int z2 = chessman.y+chessman.x;
        for(int k = 1; k < board.length; k++) {
        	if(z2 >= board.length || z2 < k) {
        		continue;
        	}
        	if(board[z2-k][k] == board[chessman.x][chessman.y]) {
                count++;
            } else {
                count = 0;
            }
            if (count == 5) {
                return true;
        	}
        }
    	return false;
    }
}

声明一个Chessman类。

public class Chessman{
	public int x;
	public int y;

	Chessman(int x ,int y){
		this.x = x;
		this.y = y;
	}
}

其中一个次的输出结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值