从C向C++18——演讲比赛流程管理系统

一.项目需求

1.比赛规则

  • 学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛。
  • 每名选手都有对应的编号,如 10001~ 10012
  • 比赛方式:分组比赛,每组6个人;
  • 第一轮分为两个小组, 整体按照选手编号进行抽签后顺序演讲.
  • 十个评委分别给每名选手打分,**去除最高分和最低分,**求的平均分为本轮选手的成绩
  • 当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛
  • 第二轮为决赛,前三名胜出
  • 每轮比赛过后需要显示晋级选手的信息

2.程序功能

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

二.界面实现

实际开发过程中,先写主界面,一些部分可以用伪代码注释,以后再慢慢实现:

c++ 复制代码
#include <iostream>
#include <ctime>
#include "speechmanger.h"
using namespace std;

int main()
{
	Speechmanger sm;
	int choice = 0;
	srand((unsigned int)time(NULL));
	while (true)
	{
		sm.showmenu();

		cout << "请您输入您的选择:" << endl;
		cin >> choice;

		switch (choice)
		{
		case 1:
			sm.startgame();                    //开始比赛
			break;
		case 2:
			sm.showrecord();                   //查看记录
			break;
		case 3:
			sm.clearfile();                    //清空文件
			break;
		case 0:
			sm.exitsystem();                   //退出系统
			break;
		default:
			system("cls");
			break;
		}
	}
	

	system("pause");
	return 0;
}

三.管理类头文件

speechmanger.h头文件:

c++ 复制代码
#pragma once
#include <iostream>
#include <string>
#include "speaker.h"
#include <vector>
#include <map>
#include <algorithm>
#include <deque>
#include <functional>
#include <numeric>
#include <fstream>
using namespace std;

//演讲管理类
class Speechmanger
{
public:
	Speechmanger();                  //构造函数
	~Speechmanger();                 //析构函数

	void showmenu();                 //显示菜单
	void exitsystem();               //退出系统
	void initspeech();               //初始化容器和属性
	void creatspeaker();             //创建选手
	void startgame();                //开始比赛
	void speechdraw();               //抽签
	void contest();                  //比赛(打分)
	double avg_score();              //计算成绩
	void showscore();                //显示得分(1)
	void showhonor();                //显示决赛获奖名单
	void saverecord();               //保存本届决赛记录
	void loadrecord();               //读取比赛记录
	void showrecord();               //显示往届记录
	void clearfile();                //清空文件



	//成员属性
	vector<int> v1;                  //保存第一轮选手编号
	vector<int> v2;                  //保存第二轮选手编号,也就是第一轮晋级选手编号
	vector<int> v3;                  //保存最后胜出3名选手编号
	map<int, Speaker> m_s;           //存放编号及其具体对应选手的容器
	int index;                       //记录当前比赛轮次
	bool fileempty;                  //文件空标志
	map<int, vector<string>> m_record;      //存放往届记录的容器
};

像我这样,属性和方法分开写。

四.方法实现

speechmanger.cpp源文件实现:

c++ 复制代码
#include "speechmanger.h"

Speechmanger::Speechmanger()
{
	this->initspeech();
	this->creatspeaker();
	this->loadrecord();
}

Speechmanger::~Speechmanger() 
{

}

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

//退出系统
void Speechmanger::exitsystem()
{
	cout << "欢迎下次使用" << endl;
	exit(0);
}

//初始化容器和属性
void Speechmanger::initspeech()
{
	//容器都置空
	this->v1.clear();
	this->v2.clear();
	this->v3.clear();
	this->m_s.clear();
	this->m_record.clear();

	//比赛轮次初始为1
	this->index = 1;

}

//创建12名选手
void Speechmanger::creatspeaker()
{
	string namesed = "ABCDEFGHILKL";
	for (int i = 0; i < namesed.size(); i++)
	{
		string name = "选手";
		name += namesed[i];
		Speaker sp;
		sp.m_name = name;
		for (int j = 0; j < 2; j++)
		{
			sp.m_score[j] = 0;
		}

		this->v1.push_back(i + 10001);                       //创建选手编号,放入v1容器中
		this->m_s.insert(make_pair(i + 10001, sp));          //记录编号和选手对应关系

	}
}

//开始比赛
void Speechmanger::startgame()
{
	//第一轮开始比赛
	//1.抽签
	this->speechdraw();
	//2.比赛(打分)
	this->contest();
	//3.显示晋级名单
	this->showscore();

	//第二轮开始比赛
	this->index++;
	//1.抽签
	this->speechdraw();
	//2.比赛(打分)
	this->contest();
	//3.显示获奖名单
	this->showhonor();
	//4.结果保存到文件中
	this->saverecord();

	//重置环境
	this->initspeech();
	this->creatspeaker();
	this->loadrecord();

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

//抽签
void Speechmanger::speechdraw()
{
	cout << "第" << this->index << "轮选手正在抽签:" << endl;
	cout << "--------------------------------------" << endl;
	cout << "抽签后的结果如下:" << endl;

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

	}
	else if (this->index == 2)
	{
		random_shuffle(v2.begin(), v2.end());
		for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
		{
			cout << *it << " ";
		}
		cout << endl;
	}
	else
		cout << "程序出现错误" << endl;

	cout << "--------------------------------------" << endl;
	system("pause");
	cout << endl;
}

//比赛(打分)
void Speechmanger::contest()
{
	cout << "---第" << this->index << "轮比赛开始:---" << endl;
	
	vector<int> v_src;                    //比赛容器
	if (this->index == 1)
		v_src = v1;
	if (this->index == 2)
		v_src = v2;

	multimap<double, int, greater<double>> groupscore;             //临时容器,存放小组成绩
	int num = 0;                //记录人数,6个人一组

	//遍历所有选手开始打分
	for (vector<int>::iterator it = v_src.begin(); it != v_src.end(); it++)
	{
		num++;
		double score = this->avg_score();
		this->m_s[*it].m_score[index - 1] = score;            //第四种插入方式

		groupscore.insert(make_pair(score,*it));
		if (num % 6 == 0)
		{
			cout << "第" << num / 6 << "小组的成绩如下:" << endl;
			for (multimap<double, int, greater<double>>::iterator dit = groupscore.begin(); dit != groupscore.end(); dit++)
			{
				cout << "编号:" << dit->second << "  姓名:" << this->m_s[dit->second].m_name
					<< "  成绩:" << this->m_s[dit->second].m_score[this->index - 1] << endl;
			}

			//取走前3名
			int count = 0;
			for (multimap<double, int, greater<double>>::iterator fit = groupscore.begin(); fit != groupscore.end()&& count<3; fit++,count++)
			{
				if (this->index == 1)
				{
					v2.push_back((*fit).second);
				}
				else
					v3.push_back((*fit).second);
			}
			groupscore.clear();
			cout << endl;
		}
	}
	cout << "---第" << this->index << "轮比赛结束---" << endl;
	system("pause");
}

//计算成绩
double Speechmanger::avg_score()
{
	deque<double> d;
	for (int i = 0; i < 10; i++)
	{
		double score = (rand() % 401 + 600) / 10.f;
		d.push_back(score);
	}

	sort(d.begin(), d.end(),greater<double>());           //降序排序
	//去除最高分和最低分
	d.pop_back();
	d.pop_front();

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

//显示得分(1)
void Speechmanger::showscore()
{
	cout << "第一轮晋级决赛选手如下:" << endl;
	for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
	{
		cout << "选手编号:" << *it << "  姓名:" << this->m_s[*it].m_name << "  得分:"
			<< this->m_s[*it].m_score[0]<<endl;
	}
	cout << endl;

	system("pause");
	system("cls");
	this->showmenu();
}

//显示决赛获奖名单
void Speechmanger::showhonor()
{
	cout << "第二轮决赛获奖选手如下:" << endl;
	for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++)
	{
		cout << "选手编号:" << *it << "  姓名:" << this->m_s[*it].m_name << "  得分:"
			<< this->m_s[*it].m_score[this->index-1] << endl;
	}
	cout << endl;

	system("pause");
	system("cls");
	this->showmenu();
}

//保存本届决赛记录
void Speechmanger::saverecord()
{
	ofstream ofs;
	ofs.open("speech.csv",ios::out | ios::app);   //以追加方式写文件
	for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++)
	{
		ofs << *it << "," << this->m_s[*it].m_name << "," << this->m_s[*it].m_score[1] <<",";
	}
	ofs<<endl;
	ofs.close();
	cout << "记录保存完毕" << endl;

	this->fileempty = false;
}

//读取比赛记录
void Speechmanger::loadrecord()
{
	ifstream ifs("speech.csv", ios::in);        //读文件

	//文件不存在
	if(!ifs.is_open())
	{
		this->fileempty = true;
		return;
	}

	//文件存在但被清空
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		this->fileempty = true;
		ifs.close();
		return;
	}

	//文件不为空
	this->fileempty = false;
	ifs.putback(ch);
	string data;
	int num = 0;
	while (ifs >> data)
	{
		vector<string> v;
		int pos = -1;          //查找","的位置
		int start = 0;         //开始查找的位置
		while (true)
		{
			pos = data.find(",", start);
			if (pos == -1)
			{
				//没有找到的情况
				break;
			}
			string temp = data.substr(start, pos - start);
			v.push_back(temp);
			start = pos + 1;
		}
		this->m_record.insert(make_pair(num, v));
		num++;
	}
	ifs.close();
}

//显示往届记录
void Speechmanger::showrecord()
{
	if (this->fileempty)
	{
		cout << "文件为空或记录不存在!" << endl;
	}
	else 
	{
		for (int i = 0; i < this->m_record.size(); i++)
		{
			cout << "第" << i + 1 << "届信息:" << endl;
			cout << "冠军编号:" << this->m_record[i][0] << " 冠军姓名:" << this->m_record[i][1] << " 冠军得分:" << this->m_record[i][2] << endl;
			cout << "亚军编号:" << this->m_record[i][3] << " 亚军姓名:" << this->m_record[i][4] << " 亚军得分:" << this->m_record[i][5] << endl;
			cout << "季军编号:" << this->m_record[i][6] << " 季军姓名:" << this->m_record[i][7] << " 季军得分:" << this->m_record[i][8] << endl;
		}
	}

	system("pause");
	system("cls");
}

//清空文件
void Speechmanger::clearfile()
{
	cout << "是否确定清空文件?" << endl;
	cout << "1、是         2、否" << endl;
	int select = 0;
	cin >> select;
	if (select == 1)
	{
		ofstream ofs("speech.csv", ios::trunc);
		ofs.close();

		this->initspeech();
		this->creatspeaker();
		this->loadrecord();
		cout << "清空成功!" << endl;
	}
	system("pause");
	system("cls");
}
相关推荐
ever_up97313 分钟前
EasyExcel的导入与导出及在实际项目生产场景的一下应用例子
java·开发语言·数据库
吴天德少侠1 小时前
c++返回一个pair类型
开发语言·c++
ok!ko1 小时前
设计模式之工厂模式(通俗易懂--代码辅助理解【Java版】)
java·开发语言·设计模式
学地理的小胖砸1 小时前
【GEE的Python API】
大数据·开发语言·前端·python·遥感·地图学·地理信息科学
八月的雨季 最後的冰吻2 小时前
C--字符串函数处理总结
c语言·前端·算法
qq_317060953 小时前
java之http client工具类
java·开发语言·http
robot_大菜鸟3 小时前
python_openCV_计算图片中的区域的黑色比例
开发语言·python·opencv
Pandaconda3 小时前
【C++ 面试 - 新特性】每日 3 题(六)
开发语言·c++·经验分享·笔记·后端·面试·职场和发展
chanTwo_003 小时前
go--知识点
开发语言·后端·golang
悟空丶1233 小时前
go基础知识归纳总结
开发语言·后端·golang