0

0

井字棋胜负判断教程:修复及优化

心靈之曲

心靈之曲

发布时间:2025-07-11 15:26:02

|

362人浏览过

|

来源于php中文网

原创

井字棋胜负判断教程:修复及优化

本文针对一个简单的井字棋游戏,重点解决了胜负判断功能失效的问题。通过分析错误原因,并提供正确的代码示例,详细讲解了如何准确地检测游戏中的获胜条件,确保程序能够正确判定胜负,并避免潜在的逻辑错误。

胜负判断逻辑修正

原代码中,胜负判断的核心问题在于使用了错误的集合方法。ArrayList 类型的 plaeyer1position 和 plaeyer2position 存储的是玩家落子的位置(整数),而 gewinner 列表中的元素是 List,代表获胜的各种位置组合。

错误代码:

if(plaeyer1position.contains(l)){
    return "Spieler 1 gewonnen";
} else if (plaeyer2position.contains(l)) {
    return "Spieler 2 gewonnen";
}

plaeyer1position.contains(l) 检查的是 plaeyer1position 是否包含整个 List 对象 l,这永远不会成立,因为 plaeyer1position 存储的是 Integer,而不是 List

正确的做法是使用 containsAll() 方法,判断 plaeyer1position 是否包含 l 中的 所有 元素。

正确代码:

北极象沉浸式AI翻译
北极象沉浸式AI翻译

免费的北极象沉浸式AI翻译 - 带您走进沉浸式AI的双语对照体验

下载
if(plaeyer1position.containsAll(l)){
    return "Spieler 1 gewonnen";
} else if (plaeyer2position.containsAll(l)) {
    return "Spieler 2 gewonnen";
}

X.containsAll(Y) 会检查 X 是否包含 Y 中的所有元素。这样,只要玩家1或玩家2占据了 gewinner 列表中的任何一个获胜组合的所有位置,就能正确判定胜负。

优化建议

除了修正胜负判断逻辑外,还可以对代码进行一些优化,提高可读性和健壮性。

  1. 代码国际化: 避免在代码中使用德语注释和输出,统一使用英语,方便代码维护和共享。
  2. 简化胜负判断: 将判断平局的逻辑放在循环外面,可以减少不必要的判断。
  3. 避免重复打印棋盘: bestimmmung_der_position 方法中调用了 gameboard 方法,导致每次落子后棋盘打印两次,可以移除 bestimmmung_der_position 方法中的 gameboard(board) 调用。
  4. 输入验证: 增加对玩家输入位置的验证,防止输入超出范围的数字或已被占用的位置。
  5. 可读性优化: 将 List 改为 List 增加代码可读性

以下是优化后的 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> 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 "Player 1 wins!";
        } else if (plaeyer2position.containsAll(l)) {
            return "Player 2 wins!";
        }
    }

    if (plaeyer1position.size() + plaeyer2position.size() == 9) {
        return "No player wins.\n";
    }

    return "";
}

完整示例代码(包含优化建议)

import java.util.*;

public class TicTacToe {

    static ArrayList plaeyer1position = new ArrayList<>();
    static ArrayList plaeyer2position = new ArrayList<>();
    public static void main(String[] args) {
        char[][] board = {{' ', '|', ' ', '|', ' '},
                {'-', '+', '-', '+', '-'},
                {' ', '|', ' ', '|', ' '},
                {'-', '+', '-', '+', '-'},
                {' ', '|', ' ', '|', ' '}};

        gameboard(board);

        Scanner scn = new Scanner(System.in); // Scanner should be initialized once

        while(true) {
            System.out.println("Player 1, enter your position (1-9):");
            int position = getValidPosition(scn, board);
            bestimmmung_der_position(board, position, "Player 1");

            gameboard(board); // Print board after Player 1's move

            String result = checkWinner();
            if (!result.isEmpty()) {
                System.out.println(result);
                break;
            }


            System.out.println("Player 2, enter your position (1-9):");
            int position2 = getValidPosition(scn, board);
            bestimmmung_der_position(board, position2, "Player 2");

            gameboard(board); // Print board after Player 2's move

            result = checkWinner();
            if (!result.isEmpty()) {
                System.out.println(result);
                break;
            }

            if (plaeyer1position.size() + plaeyer2position.size() == 9) {
                System.out.println("It's a draw!");
                break;
            }
        }

        scn.close(); // Close the scanner to prevent resource leaks
    }

    public static void gameboard(char[][] board) {
        for (char[] row : board) {
            for (char c : row) {
                System.out.print(c);
            }
            System.out.println();
        }
    }

    public static void bestimmmung_der_position(char[][] board,int position, String spieler) {

        char symbol = ' ';

        if(spieler.equals("Player 1")){
            symbol = 'X';
            plaeyer1position.add(position);
        } else if (spieler.equals("Player 2")) {
            symbol = 'O';
            plaeyer2position.add(position);
        }


        switch (position) {
            case 1:
                board[0][0] = symbol;
                break;
            case 2:
                board[0][2] = symbol;
                break;
            case 3:
                board[0][4] = symbol;
                break;
            case 4:
                board[2][0] = symbol;
                break;
            case 5:
                board[2][2] = symbol;
                break;
            case 6:
                board[2][4] = symbol;
                break;
            case 7:
                board[4][0] = symbol;
                break;
            case 8:
                board[4][2] = symbol;
                break;
            case 9:
                board[4][4] = symbol;
                break;
            default:
                break;

        }
        //gameboard(board); // Removed duplicated call
    }

    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> 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 "Player 1 wins!";
            } else if (plaeyer2position.containsAll(l)) {
                return "Player 2 wins!";
            }
        }

        return "";
    }

    public static int getValidPosition(Scanner scanner, char[][] board) {
        int position;
        while (true) {
            try {
                position = scanner.nextInt();
                if (position < 1 || position > 9) {
                    System.out.println("Invalid input. Please enter a number between 1 and 9:");
                } else if (isPositionTaken(position, board)) {
                    System.out.println("Position is already taken. Please choose another position:");
                } else {
                    break; // Valid input, exit the loop
                }
            } catch (InputMismatchException e) {
                System.out.println("Invalid input. Please enter a number:");
                scanner.next(); // Consume the invalid input to prevent an infinite loop
                continue;
            }
        }
        return position;
    }

    public static boolean isPositionTaken(int position, char[][] board) {
        switch (position) {
            case 1:
                return board[0][0] != ' ';
            case 2:
                return board[0][2] != ' ';
            case 3:
                return board[0][4] != ' ';
            case 4:
                return board[2][0] != ' ';
            case 5:
                return board[2][2] != ' ';
            case 6:
                return board[2][4] != ' ';
            case 7:
                return board[4][0] != ' ';
            case 8:
                return board[4][2] != ' ';
            case 9:
                return board[4][4] != ' ';
            default:
                return true; // Should not happen, but handle it to avoid errors
        }
    }
}

总结

通过修正 checkWinner() 方法中的集合判断逻辑,并加入输入验证等优化措施,可以使井字棋游戏更加健壮和易用。 记住,理解集合类型的区别和正确使用集合方法是编写可靠代码的关键。 此外,良好的代码风格和注释也能显著提高代码的可读性和可维护性。

相关专题

更多
PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

3

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

41

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

101

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

148

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

57

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

42

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

19

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

107

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

45

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号