C++课设----足球比赛计分系统

问题描述:采用胜一场得3分,平局各得1分,负一场得0分,排名以积分多者在前,当两队(或多队)积分相同时,则净胜球(即进球数与失球数之差)多者在前,若净胜球相同,则进球数多者在前,若仍相同,则并列。试编一程序统计最近一轮比赛后,各队积分及排名。

具体要求:

设积分表结构如下:队名,赢的场数,平的场数,负的场数,进球数,失球数,积分。积分表放在正文文件中。最近一轮的结果从键盘输入,其形式为:主队名(可用代码),客队名(可用代码),主队得分(即进球数),客队得分(即进球数)。程序应根据此轮结果修改各队的积分和名次,所得的最新记分表仍在原积分文件中并同时在屏幕上显示。

程序实现如下:

#include <iostream>
#include <list>
#include <string>
#include <fstream>
#include <map>
#include <vector>
#include <stdexcept>
#include <iomanip>

class Team {
public:
    std::string name;
    int matchesPlayed;
    int wins;
    int draws;
    int losses;
    int goalsFor;
    int goalsAgainst;
    int points;
    int ranking;

    Team() : name(""), matchesPlayed(0), wins(0), draws(0), losses(0), goalsFor(0), goalsAgainst(0), points(0), ranking(0) {}

    int goalDifference() const {
        return goalsFor - goalsAgainst;
    }

    void updateMatchResult(int scored, int conceded, int result) {
        goalsFor += scored;
        goalsAgainst += conceded;
        matchesPlayed++;

        if (result == 1) {
            wins++;
            points += 3;
        }
        else if (result == 0) {
            draws++;
            points += 1;
        }
        else {
            losses++;
        }
    }
};

bool compareTeams(const Team& a, const Team& b) {
    if (a.points != b.points)
        return a.points > b.points;
    if (a.goalDifference() != b.goalDifference())
        return a.goalDifference() > b.goalDifference();
    return a.goalsFor > b.goalsFor;
}

void readTeamsFromInput(std::list<Team>& teams) {
    int numberOfTeams;
    std::cout << "输入参赛球队数量: ";
    if (!(std::cin >> numberOfTeams) || numberOfTeams <= 0) {
        throw std::invalid_argument("无效的球队数量。请输入一个正整数。");
    }
    std::cin.ignore();

    for (int i = 0; i < numberOfTeams; ++i) {
        Team team;
        std::cout << "输入第 " << (i + 1) << " 支球队的名称: ";
        std::getline(std::cin, team.name);
        teams.push_back(team);
    }
}

void writeTeamsToFile(const std::list<Team>& teams, const std::string& filename) {
    std::ofstream file(filename);
    for (const auto& team : teams) {
        file << team.name << " " << team.matchesPlayed << " " << team.wins << " " << team.draws << " "
            << team.losses << " " << team.goalsFor << " " << team.goalsAgainst << " " << team.points << std::endl;
    }
    file.close();
}

void updateRankings(std::list<Team>& teams) {
    int rank = 1;
    for (auto& team : teams) {
        team.ranking = rank;
        rank++;
    }
}

void updateAndSortTeams(std::list<Team>& teams, const std::string& homeTeam, const std::string& awayTeam, int homeScore, int awayScore) {
    bool homeTeamFound = false;
    bool awayTeamFound = false;

    for (auto& team : teams) {
        if (team.name == homeTeam) {
            team.updateMatchResult(homeScore, awayScore, (homeScore > awayScore) ? 1 : ((homeScore == awayScore) ? 0 : 2));
            homeTeamFound = true;
        }
        if (team.name == awayTeam) {
            team.updateMatchResult(awayScore, homeScore, (awayScore > homeScore) ? 1 : ((awayScore == homeScore) ? 0 : 2));
            awayTeamFound = true;
        }
    }

    if (!homeTeamFound || !awayTeamFound) {
        throw std::invalid_argument("未找到指定的球队名称。请检查输入的球队名称是否正确。");
    }

    teams.sort(compareTeams);
    updateRankings(teams);
}

void displayTeams(const std::list<Team>& teams) {
    std::cout << std::left << std::setw(6) << "排名"
              << std::setw(20) << "球队"
              << std::setw(12) << "比赛场数"
              << std::setw(6) << "胜"
              << std::setw(6) << "平"
              << std::setw(6) << "负"
              << std::setw(10) << "进球数"
              << std::setw(12) << "失球数"
              << std::setw(10) << "总得分" << std::endl;

    for (const auto& team : teams) {
        std::cout << std::left << std::setw(6) << team.ranking
                  << std::setw(20) << team.name
                  << std::setw(12) << team.matchesPlayed
                  << std::setw(6) << team.wins
                  << std::setw(6) << team.draws
                  << std::setw(6) << team.losses
                  << std::setw(10) << team.goalsFor
                  << std::setw(12) << team.goalsAgainst
                  << std::setw(10) << team.points << std::endl;
    }
}

int main() {
    try {
        std::list<Team> teams;
        std::string filename = "teams.txt";

        readTeamsFromInput(teams);

        while (true) {
            std::string matchDateInput;
            std::string homeTeam, awayTeam;
            int homeScore, awayScore;

            std::cout << "输入比赛日期 (YYYY-MM-DD),输入 'exit' 退出: ";
            std::cin >> matchDateInput;
            if (matchDateInput == "exit") break;

            std::cin.ignore();
            std::cout << "输入主队名称: ";
            std::getline(std::cin, homeTeam);
            std::cout << "输入客队名称: ";
            std::getline(std::cin, awayTeam);
            std::cout << "输入主队进球数: ";
            std::cin >> homeScore;
            std::cout << "输入客队进球数: ";
            std::cin >> awayScore;

            updateAndSortTeams(teams, homeTeam, awayTeam, homeScore, awayScore);

            displayTeams(teams);
        }

        writeTeamsToFile(teams, filename);

        return 0;
    }
    catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
        return 1;
    }
}


在 `main` 函数中,首先创建一个空的 `std::list<Team>` 类型的 `teams` 容器,用于存储球队信息,并指定一个文件名 `filename`。
调用 `readTeamsFromInput` 函数,该函数要求输入参赛球队的数量以及每支球队的名称。输入的球队信息被添加到 `teams` 容器中。
创建了一个空的 `std::map<std::string, int>` 类型的 `matchCount` 容器,用于记录每天比赛数量的映射,以及一个空的 `std::vector<std::string>` 类型的 `matchDate` 容器,用于记录比赛日期的向量。
进入主循环,该循环允许输入比赛信息,直到输入 "exit" 为止。
在每次循环迭代中,程序要求输入比赛日期(格式为 "YYYY-MM-DD")以及主队和客队的名称,主队和客队的进球数。然后,程序调用 `updateAndSortTeams` 函数来更新球队的比赛结果和积分。
updateAndSortTeams` 函数根据主队和客队的进球数判断比赛结果,并根据比赛结果更新球队的积分信息。如果输入的球队名称无效,将抛出异常。
每次比赛信息输入后,程序会调用 `displayTeams` 函数来显示更新后的球队排名和数据。
可以继续输入更多的比赛信息,或者输入 "exit" 来退出程序。
当选择退出程序时,程序将调用 `writeTeamsToFile` 函数将最终的球队信息写入文件 "teams.txt"。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

完成时done

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值