井字棋游戏胜负判定教程:修复与优化

井字棋游戏胜负判定教程:修复与优化

本文旨在解决井字棋游戏中胜负判定逻辑错误的问题。通过分析代码,找出导致胜负判定失效的原因,并提供修复方案。此外,还将对代码进行优化,使其更加简洁易懂,提升程序的可读性和健壮性。本文将帮助读者理解如何正确实现井字棋游戏的胜负判定功能。

问题分析

原代码中,checkWinner() 函数的胜负判定逻辑存在根本性错误。它使用 plaeyer1position.contains(l) 来判断玩家 1 是否获胜,其中 plaeyer1position 是一个存储玩家 1 落子位置的 ArrayList,而 l 是一个代表获胜组合的 List。

contains() 方法用于判断列表中是否包含指定的对象。由于 plaeyer1position 存储的是 Integer 对象,而 l 是 List 对象,因此 plaeyer1position 永远不会包含 l,导致胜负判定失效。

解决方案

正确的做法是使用 containsAll() 方法,该方法用于判断列表是否包含指定集合中的所有元素。因此,需要将 plaeyer1position.contains(l) 替换为 plaeyer1position.containsAll(l),同样,plaeyer2position.contains(l) 也要替换为 plaeyer2position.containsAll(l)。

修改后的 checkWinner() 函数如下:

public static String checkWinner(){    List top_zeile = Arrays.asList(1,2,3);    List mid_zeile = Arrays.asList(4,5,6);    List bot_zeile = Arrays.asList(7,8,9);    List links_reihe = Arrays.asList(1,4,7);    List mitte_reihe = Arrays.asList(2,5,8);    List rechts_reihe = Arrays.asList(3,6,9);    List diagonale_rechts = Arrays.asList(1,5,9);    List diagonale_links = Arrays.asList(7,5,3);    List<List> gewinner = new ArrayList();    gewinner.add(top_zeile);    gewinner.add(mid_zeile);    gewinner.add(bot_zeile);    gewinner.add(links_reihe);    gewinner.add(mitte_reihe);    gewinner.add(rechts_reihe);    gewinner.add(diagonale_links);    gewinner.add(diagonale_rechts);    for(List l: gewinner){        if(plaeyer1position.containsAll(l)){            return "Spieler 1 gewonnen";        } else if (plaeyer2position.containsAll(l)) {            return "Spieler 2 gewonnen";        }    }    if(plaeyer1position.size()+plaeyer2position.size()==9){        return "Kein Spieler hat gewonnen.n";    }    return "";}

注意事项:

在创建 List 对象时,明确指定泛型类型为 Integer,避免类型转换问题。循环结束后,需要增加一个平局的判断条件,否则在棋盘填满时,可能无法正确判定平局。

代码优化

除了修复胜负判定逻辑错误外,还可以对代码进行一些优化,使其更加简洁易懂。

变量命名: 将变量名改为英文,提高代码的可读性。例如,将 top_zeile 改为 topRow,mid_zeile 改为 midRow,以此类推。

常量定义: 将玩家 1 和玩家 2 的符号定义为常量,方便修改和维护。

private static final char PLAYER1_SYMBOL = 'X';private static final char PLAYER2_SYMBOL = 'O';

简化位置判断逻辑: 可以使用一个二维数组来存储棋盘,并通过计算来确定落子位置。

public static void determinePosition(char[][] board, int position, String player) {    char symbol = (player.equals("Player 1")) ? PLAYER1_SYMBOL : PLAYER2_SYMBOL;    ArrayList playerPositions = (player.equals("Player 1")) ? plaeyer1position : plaeyer2position;    playerPositions.add(position);    int row = (position - 1) / 3 * 2;    int col = (position - 1) % 3 * 2;    board[row][col] = symbol;}

简化胜负判断逻辑: 可以将所有的获胜组合存储在一个二维数组中,然后遍历该数组进行判断。

private static final int[][] WINNING_COMBINATIONS = {        {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, // Rows        {1, 4, 7}, {2, 5, 8}, {3, 6, 9}, // Columns        {1, 5, 9}, {3, 5, 7}             // Diagonals};public static String checkWinner() {    for (int[] combination : WINNING_COMBINATIONS) {        if (plaeyer1position.containsAll(Arrays.stream(combination).boxed().collect(Collectors.toList()))) {            return "Player 1 wins!";        } else if (plaeyer2position.containsAll(Arrays.stream(combination).boxed().collect(Collectors.toList()))) {            return "Player 2 wins!";        }    }    if (plaeyer1position.size() + plaeyer2position.size() == 9) {        return "It's a draw!";    }    return "";}

完整代码示例

以下是经过修复和优化后的完整代码示例:

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Scanner;import java.util.stream.Collectors;public class TicTacToe {    private static final char PLAYER1_SYMBOL = 'X';    private static final char PLAYER2_SYMBOL = 'O';    static ArrayList plaeyer1position = new ArrayList();    static ArrayList plaeyer2position = new ArrayList();    private static final int[][] WINNING_COMBINATIONS = {            {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, // Rows            {1, 4, 7}, {2, 5, 8}, {3, 6, 9}, // Columns            {1, 5, 9}, {3, 5, 7}             // Diagonals    };    public static void main(String[] args) {        char[][] board = {                {' ', '|', ' ', '|', ' '},                {'-', '+', '-', '+', '-'},                {' ', '|', ' ', '|', ' '},                {'-', '+', '-', '+', '-'},                {' ', '|', ' ', '|', ' '}        };        printGameBoard(board);        Scanner scanner = new Scanner(System.in);        while (true) {            // Player 1 turn            System.out.print("Player 1, enter your position (1-9): ");            int position1 = scanner.nextInt();            determinePosition(board, position1, "Player 1");            printGameBoard(board);            String result = checkWinner();            if (!result.isEmpty()) {                System.out.println(result);                break;            }            // Player 2 turn            System.out.print("Player 2, enter your position (1-9): ");            int position2 = scanner.nextInt();            determinePosition(board, position2, "Player 2");            printGameBoard(board);            result = checkWinner();            if (!result.isEmpty()) {                System.out.println(result);                break;            }        }        scanner.close();    }    public static void printGameBoard(char[][] board) {        for (char[] row : board) {            for (char c : row) {                System.out.print(c);            }            System.out.println();        }    }    public static void determinePosition(char[][] board, int position, String player) {        char symbol = (player.equals("Player 1")) ? PLAYER1_SYMBOL : PLAYER2_SYMBOL;        ArrayList playerPositions = (player.equals("Player 1")) ? plaeyer1position : plaeyer2position;        playerPositions.add(position);        int row = (position - 1) / 3 * 2;        int col = (position - 1) % 3 * 2;        board[row][col] = symbol;    }    public static String checkWinner() {        for (int[] combination : WINNING_COMBINATIONS) {            if (plaeyer1position.containsAll(Arrays.stream(combination).boxed().collect(Collectors.toList()))) {                return "Player 1 wins!";            } else if (plaeyer2position.containsAll(Arrays.stream(combination).boxed().collect(Collectors.toList()))) {                return "Player 2 wins!";            }        }        if (plaeyer1position.size() + plaeyer2position.size() == 9) {            return "It's a draw!";        }        return "";    }}

总结

本文详细分析了井字棋游戏中胜负判定逻辑错误的原因,并提供了修复方案。通过使用 containsAll() 方法,可以正确判断玩家是否获胜。此外,还对代码进行了优化,使其更加简洁易懂,提高了代码的可读性和可维护性。希望本文能够帮助读者更好地理解井字棋游戏的实现原理,并能够编写出更加健壮和高效的代码。

以上就是井字棋游戏胜负判定教程:修复与优化的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/138090.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月30日 12:27:52
下一篇 2025年11月30日 12:48:12

相关推荐

  • PHP怎么实现邮件发送 PHP邮件发送的完整配置教程

    php实现邮件发送建议使用phpmailer库并配置smtp。1. 开启openssl扩展以支持安全连接;2. 选择可靠的smtp服务器如qq邮箱或专业服务商;3. 使用phpmailer简化代码,配置smtp参数如host、username、password等;4. 设置邮件内容格式、收件人及附件…

    2025年12月10日 好文分享
    000
  • PHP如何调用Go语言程序 调用Go程序的3种交互方式

    php调用go程序有三种方式:命令行调用、http服务和使用扩展。1. 命令行调用是通过exec等函数执行go可执行文件,优点是实现简单,适合非频繁调用;缺点是每次调用都要启动新进程,效率低。2. http服务是让go作为服务器接收php的http请求,优点是并发性能好,数据交换方便;缺点是需编写g…

    2025年12月10日 好文分享
    000
  • 支付宝php回调接口怎么写 php支付宝支付回调详细指南

    如何配置支付宝回调接口?首先,登录支付宝开放平台,找到你的应用,设置回调url为部署代码的公网地址;确保使用内网穿透工具使测试环境可访问。支付宝回调有哪些参数?如何安全处理?回调包括out_trade_no(订单号)、trade_no(交易号)、trade_status(状态)、total_amou…

    2025年12月10日 好文分享
    000
  • PHP如何获取RAID卡信息 RAID硬件信息获取方法

    获取php中的raid卡信息需借助操作系统工具,因php本身无法直接访问硬件。1.确定服务器操作系统,linux可用lspci、mdadm –detail /dev/md0、smartctl获取raid卡及磁盘信息;windows可用wmic或powershell命令。2.php通过ex…

    2025年12月10日 好文分享
    000
  • PHP如何实现数据库索引优化 数据库索引优化技巧分享助你提升查询性能

    php实现数据库索引优化需从索引类型选择、创建策略及查询语句优化三方面入手。1. 选择合适的索引类型:b-tree适用于等值、范围查询和排序;哈希索引仅适用于等值查询;全文索引用于文本关键词搜索;空间索引用于地理位置查询。2. 最佳索引创建策略包括:选择区分度高的列、使用组合索引覆盖多条件查询、避免…

    2025年12月10日 好文分享
    000
  • PHP怎样处理JWT令牌 处理JWT令牌的5个安全要点

    php处理jwt需选成熟库如firebase/php-jwt,1.使用环境变量存储密钥;2.通过jwt::encode生成令牌;3.用jwt::decode验证签名及有效期;4.传输时采用authorization头;5.结合刷新令牌机制延长访问周期;6.防篡改依赖签名与https;7.撤销可通过黑…

    2025年12月10日 好文分享
    000
  • PHP如何调用PostHTML处理 PostHTML调用步骤解析

    要在服务器上安装node.js和posthtml,首先根据操作系统选择安装方式,linux系统可用包管理器安装node.js,随后通过npm install -g posthtml全局安装posthtml。配置posthtml插件时,使用json字符串指定插件名称及选项,并通过命令行参数-p传递。p…

    2025年12月10日 好文分享
    000
  • PHP如何调用Babel转译 JavaScript代码转译指南

    如何用php调用babel转译javascript代码?答案是利用php执行系统命令的能力调用node.js环境下的babel cli。1. 确保服务器安装了node.js和npm;2. 安装babel cli及核心库,如@babel/core和@babel/preset-env;3. 在php中使…

    2025年12月10日 好文分享
    000
  • PHP如何调用Git大文件存储 Git大文件存储调用教程

    php调用git大文件存储需通过git lfs实现,具体步骤为:1. 安装并配置git lfs客户端;2. 初始化git仓库;3. 使用git lfs track声明需管理的大文件类型;4. 将.gitattributes加入版本控制;5. 编写php脚本执行git命令,推荐使用exec()函数并处…

    2025年12月10日 好文分享
    000
  • PHP中的队列:如何使用Redis实现任务队列

    php中使用redis实现任务队列的核心方法是利用redis的列表数据结构,通过lpush推入任务、brpop阻塞获取任务,并结合序列化与反序列化处理任务数据。具体步骤如下:1. 任务生产者连接redis,将任务数据序列化后使用lpush命令推入队列;2. 任务消费者连接redis,使用brpop命…

    2025年12月10日 好文分享
    000
  • PHP MySQL数据入库详细步骤解析

    要安全高效地将php数据存入mysql,需遵循连接数据库、构建sql语句、执行语句三步骤,并采取以下措施保障安全与效率:1. 使用预处理语句防止sql注入,通过pdo或mysqli绑定参数实现数据与sql结构分离;2. 对用户输入使用mysqli_real_escape_string()函数转义或进…

    2025年12月10日 好文分享
    000
  • PHP怎样处理Kerberos认证 Kerberos集成的4个步骤解析

    kerberos认证在php中的作用是提供一种高安全性的身份验证机制,用于安全访问内部服务、实现单点登录(sso)和提升整体安全性。1. 安全访问内部服务:通过kerberos“通行证”机制,避免直接暴露用户名密码;2. 实现单点登录:用户只需一次登录即可访问多个应用;3. 提升安全性:使用加密技术…

    2025年12月10日 好文分享
    000
  • PHP中的会话:如何使用Session管理用户登录状态

    php中的会话(session)是一种在服务器端存储用户信息以保持状态的机制。1.启动会话需在脚本顶部调用session_start()函数;2.使用$_session变量存储用户数据,如用户id和用户名;3.在其他页面通过session_start()访问已存储的数据;4.销毁会话时调用sessi…

    2025年12月10日 好文分享
    000
  • PHP中的事件溯源:如何实现可追溯的数据变更

    事件溯源是一种通过记录状态变化事件而非直接存储当前状态的数据管理方法,其核心在于将数据变更视为不可变事件,并按序存储以实现完整历史追溯。1. 定义事件:明确领域模型并定义具体事件,如userregistered、useremailchanged等,每个事件包含必要信息用于状态重建。2. 事件存储:选…

    2025年12月10日 好文分享
    000
  • PHP连接AWS RDS MySQL PHP操作云数据库指南

    php连接aws rds mysql的关键步骤包括配置安全组与权限、设置连接超时与字符集、优化性能及监控诊断。1. 安全配置方面,应限制rds访问ip,仅允许应用服务器ip,并遵循最小权限原则,设置强密码;2. 连接超时问题可通过设置connect_timeout参数或使用持久连接解决,同时确保应用…

    2025年12月10日 好文分享
    000
  • PHP怎样解析DEB安装包 DEB包信息提取的2种方法

    解析deb安装包主要有两种方法:1.直接解压deb包并读取控制文件,2.使用dpkg命令获取信息。第一种方法更灵活,适用于需要自定义解析逻辑或提取其他文件的场景;第二种方法更便捷,依赖系统环境中的dpkg工具。两种方法均可通过php实现,其中解压方式涉及ar和tar命令处理归档文件,并解析contr…

    2025年12月10日 好文分享
    000
  • PHP怎样解析GraphQL查询 解析GraphQL的5个专业技巧

    php解析graphql查询的解决方案是使用webonyx/graphql-php库,步骤包括:1. 通过composer安装graphql php库;2. 定义schema,包括对象类型、字段、根查询和变更类型;3. 接收客户端发送的graphql查询字符串;4. 使用graphql库执行查询并处…

    2025年12月10日 好文分享
    000
  • PHP中interface和abstract class的区别

    interface与abstract class的核心区别在于:1.interface定义行为规范,强调“有什么能力”,而abstract class提供可继承的基础类,强调“是什么”;2.interface只能包含方法签名(php 8.1前),不支持状态存储,但一个类可实现多个interface以…

    2025年12月10日 好文分享
    000
  • PHP怎样处理JWT身份验证 JWT令牌验证的5个步骤解析

    jwt验证在php中需先接收并解析令牌,验证签名和声明,最后进行授权。具体步骤为:1.接收jwt并存储于header或cookie;2.解析jwt获取header、payload、signature;3.用密钥重新计算签名并比对;4.验证payload中的声明如exp、iss等;5.通过验证后根据用…

    2025年12月10日 好文分享
    000
  • PHP怎么实现数据交叉查询 数据交叉查询优化方法详解

    php实现数据交叉查询的核心在于编写合适的sql语句,并在数据量大时进行优化。1. 使用join语句,如inner join、left join等,将多个表按逻辑关联;2. 利用子查询实现嵌套条件筛选;3. 结合复杂条件提升查询灵活性;4. 建立索引提高查询速度;5. 避免select *,只选择必…

    2025年12月10日 好文分享
    000

发表回复

登录后才能评论
关注微信