算法015:井字游戏-设计一个算法,判断玩家是否赢了井字游戏。输入是一个 N x N 的数组棋盘,由字符“ “,“X“和“O“组成,其中字符“ “代表一个空位。

本文介绍了一种用于判断井字游戏胜负的算法。通过分析棋盘状态,该算法能够准确判断出游戏是否结束,以及哪一方玩家获胜,或者游戏是否以平局结束。文章还提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
 井字游戏
设计一个算法,判断玩家是否赢了井字游戏。输入是一个 N x N 的数组棋盘,由字符" ","X"和"O"组成,其中字符" "代表一个空位。

以下是井字游戏的规则:
玩家轮流将字符放入空位(" ")中。
第一个玩家总是放字符"O",且第二个玩家总是放字符"X"。
"X"和"O"只允许放置在空位中,不允许对已放有字符的位置进行填充。
当有N个相同(且非空)的字符填充任何行、列或对角线时,游戏结束,对应该字符的玩家获胜。
当所有位置非空时,也算为游戏结束。
如果游戏结束,玩家不允许再放置字符。
如果游戏存在获胜者,就返回该游戏的获胜者使用的字符("X"或"O");如果游戏以平局结束,则返回 "Draw";如果仍会有行动(游戏未结束),则返回 "Pending"。

示例 1:
输入: board = ["O X"," XO","X O"]
输出: "X"

示例 2:
输入: board = ["OOX","XXO","OXO"]
输出: "Draw"
解释: 没有玩家获胜且不存在空位

示例 3:
输入: board = ["OOX","XXO","OX "]
输出: "Pending"
解释: 没有玩家获胜且仍存在空位

提示:
这个题目时对对战双发的战时瞬态做一个分析。
大家一定要注意审题,只存在以下四种情况
行
列
左对角线,题目说的是对角线,不是任何一条斜着的连线哦。 请一定注意,#字游戏是往格子里面放棋子,不是线上,对角线的个数也是n,不会玩的,可以先完两把,业务不熟练,危害不浅。我就想的复杂了。
右对角线,题目说的是对角线,不是任何一条斜着的连线哦。

思路:**求值法**,行列斜相同形状int值相加,如果等于*n的值,说明胜利,另外设置一个flag,存放是否空位,else就是Pendding了。
另外要特别注意,传入的是一个String类型的一维数组。

1.代码如下 Tictactoe.java:

package com.yuhl.right.leetcode;

/**
 * @author yuhl
 * @Date 2020/10/25 7:39
 * @Classname Tictactoe
 * @Description
 * 井字游戏
 * 设计一个算法,判断玩家是否赢了井字游戏。输入是一个 N x N 的数组棋盘,由字符" ","X"和"O"组成,其中字符" "代表一个空位。
 *
 * 以下是井字游戏的规则:
 * 玩家轮流将字符放入空位(" ")中。
 * 第一个玩家总是放字符"O",且第二个玩家总是放字符"X"。
 * "X"和"O"只允许放置在空位中,不允许对已放有字符的位置进行填充。
 * 当有N个相同(且非空)的字符填充任何行、列或对角线时,游戏结束,对应该字符的玩家获胜。
 * 当所有位置非空时,也算为游戏结束。
 * 如果游戏结束,玩家不允许再放置字符。
 * 如果游戏存在获胜者,就返回该游戏的获胜者使用的字符("X"或"O");如果游戏以平局结束,则返回 "Draw";如果仍会有行动(游戏未结束),则返回 "Pending"。
 *
 * 示例 1:
 * 输入: board = ["O X"," XO","X O"]
 * 输出: "X"
 *
 * 示例 2:
 * 输入: board = ["OOX","XXO","OXO"]
 * 输出: "Draw"
 * 解释: 没有玩家获胜且不存在空位
 *
 * 示例 3:
 * 输入: board = ["OOX","XXO","OX "]
 * 输出: "Pending"
 * 解释: 没有玩家获胜且仍存在空位
 *
 * 提示:
 * 1 <= board.length == board[i].length <= 100
 * 输入一定遵循井字棋规则
 */
public class Tictactoe {
    public static void main(String[] args) {
        String[] boad = {"O X"," XO","X O"};
//        String[] boad = {"OOX","XXO","OXO"};
//        String[] boad = {"OOX","XXO","OX "};
        String tictactoe = tictactoe(boad);
        System.out.println(tictactoe);
    }
    public static String tictactoe(String[] board) {

        //这个题目时对对战双发的战时瞬态做一个分析。
        //大家一定要注意审题,只存在以下四种情况
        //行
        //列
        //左对角线,题目说的是对角线,不是任何一条斜着的连线哦。 请一定注意,#字游戏是往格子里面放棋子,不是线上,对角线的个数也是n,不会玩的,可以先完两把,业务不熟练,危害不浅。我就想的复杂了。
        //右对角线,题目说的是对角线,不是任何一条斜着的连线哦。
        //
        //总体思路:求值法,行列斜相同形状int值相加,如果等于*n的值,说明胜利,另外设置一个flag,存放是否空位,else就是Pendding了。
        //另外要特别注意,传入的是一个String类型的一维数组。
        int heng ;// 记录横的和值, 局部变量必须先赋值再使用哦!
        int zong ;//记录纵的和值
        int left = 0;//记录左撇的和值
        int right = 0;//记录右捺的和值
        boolean includeempty = false;//含有空格,默认位没有,false

        int length = board.length;//记录字符串数组的长度

        for(int i=0;i<length;i++){
            heng = 0;//记录第0行(习惯,也就是第0行的总和,第二次的话就是第0行的总和,便于理解)
            zong = 0;//记录第0列(习惯,也就是第1列的总和,第二次的话就是第1列的总和,便于理解)
            for(int j=0; j<length; j++){
                heng += (int)board[i].charAt(j);//把第0行,第0列的元素给heng,之后是第0行,第1列;之后是第0行第2列... ...
                zong += (int)board[j].charAt(i);//把第0列,第0行的元素给zong,之后是第1列,第0行;之后是第2列第0行... ...
                if(board[i].charAt(j) == ' ') includeempty = true;//如果含有一个空格,则标注含有空格。 每一个位置均有走过。
            }
            //至此,第i行列的综合出来了。做个判断,如果有胜出的就停止。如果有位空的就更新includeempty位true
            if((heng == (int)'X' * length) || (zong == (int)'X' *length)) return "X";//如果横或者纵全为X,则返回X,停止程序 解释:如果整行或者整列位同一个字符,则正好满足等式。
            if((heng == (int)'O' * length) || (zong == (int)'O' *length)) return "O";//如果横或者纵全为O,则返回O,停止程序

            //左撇的和
            left += (int)board[i].charAt(i);
            //右捺的和
            right += (int)board[i].charAt(length-i-1);
        }

        //位层for循环结束后左撇和右捺的和计算完毕,可以做判断了。
        if((left == (int)'X' * length) || (right == (int)'X' *length)) return "X";
        if((left == (int)'O' * length) || (right == (int)'O' *length)) return "O";
        if(includeempty == true) return "Pending";
        return "Draw";

    }
}

2.执行结果:

"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" 
X
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值