【c++系列】项目实战—演讲比赛管理系统

需求描述

  • 学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛。
  • 比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛
  • 每名选手都有对应的编号,如 10001 ~ 10012
  • 第一轮分为两个小组,每组6个人。 整体按照选手编号进行抽签后顺序演讲。
  • 当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛。
  • 第二轮为决赛,前三名胜出
  • 每轮比赛过后需要显示晋级选手的信息

功能实现

  • 开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下一个阶段
  • 查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csv后缀名保存
  • 清空比赛记录:将文件中数据清空
  • 退出比赛程序:可以退出当前程序

知识点:面向对象思想、文件操作、STL

设计&&实现

在面向对象思想中,万物皆对象,要设计一个演讲比赛管理系统,最直接的是创建一个对象(类)管理比赛,这个对象包含主持比赛等一系列功能(方法)。在程序入口处(主函数)创建这个对象,然后在不同的时机使用这个对象不同的功能。

参赛队员类

在管理系统中,参赛队员也是一个对象,类的设计如下:

#include<iostream>
#include<string>

using namespace std;

class Speechers {
public:
    string name;
    double score[2];
};

比赛管理类

  1 #include<iostream>
  2 #include<vector>
  3 #include<map>
  4 #include<algorithm>
  5 #include "speechers.h"
  6 using namespace std;
  7
  8 class SpeechManager {
  9 public:
 10     SpeechManager(){
 11         this->init_speechers();
 12         this->create_speechers();
 13         this->load_record();
 14     };
 15
 16     ~SpeechManager(){};
 17
 18     void show_menu();
 19     void exit_system();
 20     void init_speechers(); //初始化比赛相关属性
 21     void create_speechers();
 22
 23     // 比赛流程控制
 24     void process_game();
 25     // 抽签
 26     void draw();
 27     // 开始比赛
 28     void start_game();
 29     // 显示成绩
 30     void show_score();
 31     // 保存比赛记录
 32     void save();
 33     // 读取记录
 34     void load_record();
 35     // 展示往届记录
 36     void show_record();
 37     // 清空记录
 38     void clear_record();
 39 public:
 40     // game attributes
 41     int m_index;
 42     vector<int> v1; // 选手编号
 43     vector<int> v2; // 第一轮晋级
 44     vector<int> v3; // 胜者
 45     bool is_empty;
 46     map<int, Speechers> m_speechers;
 47     map<int, vector<string> > m_record;
 48 };

实现类如下:
在这个设计类中包含一些开发小思维,比如随机数和随机种子使用,使用如何使用容器保存获胜者信息(主要逻辑在这里),文件的使用,其他的都是一些简单的操作,没啥思维性。

// show menu
void SpeechManager::show_menu() {
    cout << "********************************************" << endl;
    cout << "*************  欢迎参加演讲比赛 ************" << endl;
    cout << "*************  1.开始演讲比赛  *************" << endl;
    cout << "*************  2.查看往届记录  *************" << endl;
    cout << "*************  3.清空比赛记录  *************" << endl;
    cout << "*************  0.退出比赛程序  *************" << endl;
    cout << "********************************************" << endl;
//  cout << endl;
}

//exit
void SpeechManager::exit_system() {
    cout << "欢迎下次使用" << endl;
    system("read");
    exit(0);
}

// init attributes
void SpeechManager::init_speechers() {
    this->v1.clear();
    this->v2.clear();
    this->v3.clear();
    this->v3.clear();
    this->m_speechers.clear();
    this->m_index = 1;

    this->m_record.clear();
}

//create speechers
void SpeechManager::create_speechers() {
    // 随机命名
    string name_seed = "ABCDEFGHIJKL";
    for (int i = 0; i < name_seed.size(); i++) {
        string name = "选手";
        name += name_seed[i];

        Speechers sp;
        sp.name = name;
        for (int j = 0; j < 2; j++) {
            sp.score[j] = 0;
        }

        // 选手编号
        this->v1.push_back(i+10001);

        // 选手编号、选手放到容器中
        this->m_speechers.insert(make_pair(i+10001,sp));
    }

}

// process game
void SpeechManager::process_game() {
    // 第一轮比赛
    // 1.抽签
    this->draw();

    // 2.比赛
    this->start_game();

    // 3.显示晋级结果
    this->show_score();

    // 第二轮比赛
    this->m_index++;
    // 1.抽签
    this->draw();
    // 2.比赛
    this->start_game();
    // 3.显示晋级结果
    this->show_score();

    // 保存分数
    this->save();
    // 重置比赛
    this->init_speechers();
    this->create_speechers();
    this->load_record();

    cout << "本届比赛结束!" << endl;
    system("read");
    system("clear");
    cout << endl;
}

// draw
void SpeechManager::draw() {
    cout << "第 << " << this->m_index << " >> 轮比赛选手正在抽签"<< endl;
    cout << "---------------------" << endl;
    cout << "抽签后演讲顺序如下:" << endl;

    if (this->m_index == 1) {
        random_shuffle(v1.begin(), v1.end());
        for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it) {
            cout << *it << " " << endl;
        }
        cout << endl;
    } else {
        random_shuffle(v2.begin(), v2.end());
        for (vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
            cout << *it << " " << endl;
        }
        cout << endl;
    }
    cout << "---------------------" << endl;
    system("read");
    cout << endl;
}

// start game
void SpeechManager::start_game() {
    cout << "------------- 第"<< this->m_index << "轮正式比赛开始:------------- " << endl;

    multimap<double, int, greater<double> > groupScore; // 临时容器,保存分数、人员编号
    int num = 0;

    // 比赛人员
    vector<int> competitors;
    if (this->m_index == 1) {
        competitors = v1;
    } else {
        competitors = v2;
    }

    // traverse competitors and give grade
    for (vector<int>::iterator it = competitors.begin(); it != competitors.end(); ++it) {
        num++;
        deque<double> que; // save grade
        for (int i = 0; i < 10; i++) {
            double grade = (rand() % 401 + 600) / 10.f; // 随机生成60-100之间的分数
            que.push_back(grade);
        }
        sort(que.begin(),que.end(),greater<double>());
        que.pop_front();
        que.pop_back();

        double sum = accumulate(que.begin(), que.end(), 0.0f);
        double avg = sum / (double)que.size();

//        cout << "编号: " << *it  << " 选手: " << this->m_speechers[*it].name <<  " 获取平均分为: " << avg << endl;  //打印分数
        this->m_speechers[*it].score[this->m_index-1] = avg;

        // 6人一组,容器保存
        groupScore.insert(make_pair(avg, *it));
        if (num % 6 == 0) {
           cout << "第" << num / 6 << "小组比赛名次:" << endl;
           for (multimap<double, int, greater<double> >::iterator it = groupScore.begin(); it != groupScore.end(); it++) {
               cout << "编号: " << it->second << " 姓名: " << this->m_speechers[it->second].name << " 成绩: " << this->m_speechers[it->second].score[this->m_index - 1] << endl;
           }

           int count = 0;
           // 取前三名
           for (multimap<double, int, greater<double> >::iterator it = groupScore.begin(); it != groupScore.end() && count < 3; ++it) {
               if (this->m_index == 1) {
                   v2.push_back((*it).second);
               } else {
                   v3.push_back((*it).second);
               }
           }
           groupScore.clear();
        }
    }
    cout << "------------- 第" << this->m_index << "轮比赛完毕  ------------- " << endl;
    system("read");
}

// show score
void SpeechManager::show_score() {
    cout << "---------第" << this->m_index << "轮晋级选手信息如下:-----------" << endl;
    vector<int> up;
    if (this->m_index == 1)
    {
        up = v2;
    }
    else
    {
        up = v3;
    }

    for (vector<int>::iterator it = up.begin(); it != up.end(); it++)
    {
        cout << "选手编号:" << *it << " 姓名: " << m_speechers[*it].name << " 得分: " << m_speechers[*it].score[this->m_index - 1] << endl;
    }
    cout << endl;

    system("read");
    system("clear");
    this->show_menu();
}

// save to file
void SpeechManager::save() {
    ofstream ofs;
    ofs.open("speech.csv", ios::out | ios::app);

    for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++) {
        ofs << *it << ":" << m_speechers[*it].score[1] << ",";
    }
    ofs << endl;
    //关闭文件
    ofs.close();

    cout << "记录已经保存" << endl;
    this->is_empty = true;
}


// file is empty
void SpeechManager::load_record() {
    ifstream ifs("speech.csv", ios::in);
    if(!ifs.is_open()) {
        this->is_empty = true;
        cout << "文件不存在!" << endl;
        ifs.close();
        return;
    }

    char ch;
    ifs >> ch;
    if (ifs.eof()) {
        this->is_empty = true;
        cout << "文件为空!" << endl;
        ifs.close();
        return;
    }
    //文件不为空
    this->is_empty = false;

    ifs.putback(ch); //读取的单个字符放回去
    string data;
    int index = 0;
    while(ifs>>data) {
        vector<string> v;
        int start = 0;
        int pos = -1;

        while (true) {
            pos = data.find(",", start);
            if (-1 == pos) {
                break;
            }

            string tmp = data.substr(start, pos-start);
            v.push_back(tmp);
            start = pos + 1;
        }
        this->m_record.insert(make_pair(index,v));
        index++;
    }
    ifs.close();
}

// show record
void SpeechManager::show_record() {
    if(this->is_empty) {
        cout << "文件不存在或记录为空" << endl;
        return;
    }
    for (int i = 0; i < this->m_record.size(); i++) {
        cout << "第" << i + 1 << "届 " <<
            "冠军编号:" << this->m_record[i][0] << " 得分:" << this->m_record[i][1] << " "
            "亚军编号:" << this->m_record[i][2] << " 得分:" << this->m_record[i][3] << " "
            "季军编号:" << this->m_record[i][4] << " 得分:" << this->m_record[i][5] << endl;
    }
    system("read");
    system("clear");
}

// clear record
void SpeechManager::clear_record() {
    cout << "确认清空?" << endl;
    cout << "1、确认" << endl;
    cout << "2、返回" << endl;

    int select = 0;
    cin >> select;

    if (select == 1) {
        //打开模式 ios::trunc 如果存在删除文件并重新创建
        ofstream ofs("speech.csv", ios::trunc);
        ofs.close();

        //初始化属性
        this->init_speechers();

        //创建选手
        this->create_speechers();

        //获取往届记录
        this->load_record();


        cout << "清空成功!" << endl;
    } else {
        this->show_menu();
    }

    system("read");
    system("clear");
}

code

tar格式,包含可执行文件a.out。(5积分,没有积分的话评论留下邮箱)

资源下载

界面展示

主目录:
在这里插入图片描述
比赛流程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看往届记录
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值