<C++>12 项目:演讲比赛管理系统
本文最后更新于:2023年6月27日 上午
12 项目:演讲比赛管理系统
12.1 项目需求
共有 12 名选手,编号 10001 - 10012
比赛分为 2 轮:
- 第一轮比赛分为 2 组分别进行。每组前 3 名晋级下一轮比赛
- 第二轮比赛的前 3 名胜出
打分方式:10 个评委分别对每位选手打分,去除最高分和最低分,剩余的平均分为选手本轮成绩
每轮比赛过后,显示晋级选手(胜出选手)的信息
选手信息:姓名、编号、性别、成绩、排名
打分范围:0 - 100(随机)
菜单:
- 选手报名
- 选手信息变更
- 选手查询(按姓名、编号查找)
- 开始比赛
- 显示选手信息、轮次信息(输出至 .csv 文档)
- 随机打分、手动打分
- 确认晋级选手(输出至 .csv 文档)
- 第二轮
- 确认胜出选手(输出至 .csv 文档)
- 查看往届记录
- 清空比赛记录
- 退出系统
附录
演讲比赛管理系统
执行以下代码:
#include "menu.h"
int main() {
menu0();
}
#头文件
player.h
包含 Player 类、Com 类
Player 类:选手类。对象包含选手信息(ID、姓名、得分)。
该类包含一个静态容器,代表参赛选手的集合
Com 类:仿函数。实现对 Player* 的按 socre 的比较
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<set>
#include<fstream>
class Com;
class Player {
public:
static int id_count; // ID 计数。实例化时的 ID 值一般从 10000 开始
static set<Player*, Com>* players; // 静态容器,代表参赛选手的集合
Player(string name); // 构造方法。传入姓名
~Player(); // 析构方法。是空实现
string print(); // 返回选手信息的字符串
void set_socre(double s);
double get_socre();
void set_name(string s);
string get_name();
int get_id();
static void initial(); // 初始化 Player 类。会清空参赛选手,并重置 ID 计数
static void flush(set<Player*, Com>& p); // 用新的选手集合取代目前的集合
bool operator>(Player& p);
bool operator<(Player& p);
bool operator==(Player& p);
private:
double socre = 0; // 选手得分,初始为 -1
int id; // 选手 ID。不能更改
string name; // 选手姓名
};
class Com {
public:
bool operator()(Player* p1, Player* p2) const;
};
menu.h
程序入口。包含了大部分方法
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<set>
#include<vector>
#include<algorithm>
#include<fstream>
#include<numeric>
#include "player.h"
void menu0(); // 程序主方法
void showMenu0(); // 仅展示菜单
void add_player(); // 添加一位选手
void affirm_player(); // 查找选手
Player* affirm_by_id(int id); // 按照 ID 查找选手
Player* affirm_by_name(const string& name); // 按照姓名查找选手
void changePlayer(); // 变更选手信息
void start_match(); // 开始比赛
set<Player*, Com>& round1(set<Player*, Com>& p); // 第一轮比赛
double socre(); // 生成一个随机的分数
set<Player*, Com>& round2(set<Player*, Com>& p); // 第二轮比赛
void histroy(); // 查看历史记录
void clear_histroy(); // 清空历史记录
void write(); // 将目前的赛况导出
void show_all(); // 展示参赛选手信息
bool log_out(); // 退出程序前的确认
#源文件
player.cpp
#include "player.h"
Player::Player(string name) { // 构造器。每次构造时会更新随机值的种子
this->id = ++id_count;
this->name = name;
this->socre = -1;
srand((unsigned)time(NULL));
}
Player::~Player() {} // 析构函数。是空实现
string Player::print() { // 返回选手信息的字符串。项之间以 \t 分隔
return to_string(id) + "\t" + name + "\t" + (socre < 0 ? "-" : (to_string(socre)));
}
void Player::set_socre(double s) {
this->socre = s;
};
double Player::get_socre() {
return this->socre;
};
void Player::set_name(string s) {
this->name = s;
};
string Player::get_name() {
return this->name;
};
int Player::get_id() {
return this->id;
};
void Player::flush(set<Player*, Com>& p) { // 静态方法。该方法会替换原先的参赛选手集合
if (Player::players != NULL) {
delete Player::players;
Player::players = NULL;
}
Player::players = &p;
};
bool Player::operator>(Player& p) {
if (this->socre != p.socre) {
return this->socre > p.socre;
} else return this->id > p.id;
};
bool Player::operator<(Player& p) {
return p > *this;
};
bool Player::operator==(Player& p) {
return p.id == this->id && p.name == this->name;
};
void Player::initial() { // 静态方法。该方法会清空参赛选手集合,并重置 ID 计数
Player::id_count = 10000;
if (Player::players != NULL) delete Player::players;
Player::players = NULL;
Player::players = new set<Player*, Com>;
};
// 以下是两个静态变量的初始化
int Player::id_count = 10000;
set<Player*, Com>* Player::players = new set<Player*, Com>;
bool Com::operator()(Player* p1, Player* p2) const { // 仿函数,比较两个 Player*
if (p1->get_socre() != p2->get_socre()) {
return p1->get_socre() > p2->get_socre();
}
else return p1->get_id() > p2->get_id();
};
menu.cpp
#include "menu.h"
void showMenu0() {
cout << "————————·演讲比赛:★:管理系统·————————" << endl;
cout << "\t\t1.选 手 报 名" << endl;
cout << "\t\t2.选 手 查 询" << endl;
cout << "\t\t3.变 更 选 手" << endl;
cout << "\t\t4.比 赛 开 始" << endl;
cout << "\t\t5.查 看 往 届 记 录" << endl;
cout << "\t\t6.清 空 比 赛 记 录" << endl;
cout << "\t\t7.查 看 全 部 选 手" << endl;
cout << "\t\t9.退 出 系 统" << endl;
};
void menu0() {
bool running = true;
while (running) {
showMenu0();
int choice = 0;
cout << "请输入您的选择:";
cin >> choice;
cout << endl << "——————————————————————" << endl;
switch (choice) {
case 1:
add_player();
break;
case 2:
affirm_player();
break;
case 3:
changePlayer();
break;
case 4:
start_match();
break;
case 5:
histroy();
break;
case 6:
clear_histroy();
break;
case 7:
show_all();
break;
case 9:
if (log_out()) running = false;
break;
default:
cout << "输入有误,请重新输入!" << endl;
break;
}
system("pause");
system("cls");
}
};
void add_player() {
if (Player::players->size() >= 12) {
cout << "选手数量已满!(最多 12 人)" << endl;
return;
}
cout << "========= 添 加 选 手 =========" << endl << "请输入选手姓名:";
string name;
cin >> name;
Player* temp = new Player(name);
Player::players->insert(temp);
cout << endl << "选手信息:" << temp->print() << endl;
cout << "继续吗?(Y / N):";
char confirm = 'N';
cin >> confirm;
if (confirm == 'Y' || confirm == 'y' || confirm == '1') {
cout << endl;
add_player();
}
};
void affirm_player() {
if (Player::players->size() == 0) {
cout << "目前暂无选手报名。" << endl;
return;
}
cout << "========= 查 找 选 手 =========" << endl << "请输入查找方法(1[id] / 2[姓名]):";
int choice = 1;
cin >> choice;
if (choice == 2) {
cout << "========= 姓 名 查 找 =========" << endl;
cout << "请输入姓名:";
string s;
cin >> s;
affirm_by_name(s);
}
else if (choice == 1) {
cout << "========= ID 查 找 =========" << endl;
cout << "请输入 ID:";
cin >> choice;
affirm_by_id(choice);
}
else {
cout << "返回菜单。" << endl;
return;
}
};
Player* affirm_by_id(int id) {
for (set<Player*>::const_iterator i = Player::players->begin(); i != Player::players->end(); i++) {
Player* temp = *i;
if (temp->get_id() == id) {
cout << "找到以下选手:" << temp->print() << endl;
return *i;
}
}
cout << "未找到该选手信息" << endl;
return NULL;
};
Player* affirm_by_name(const string& name) {
bool found = false;
set<Player*> ss;
for (set<Player*>::const_iterator i = Player::players->begin(); i != Player::players->end(); i++) {
Player* temp = *i;
if (temp->get_name() == name) {
ss.insert(*i);
found = true;
}
}
if (!found) {
cout << "未找到该选手信息" << endl;
return NULL;
}
else {
cout << "找到以下 " << ss.size() << " 位选手:" << endl;
for (set<Player*>::const_iterator i = ss.begin(); i != ss.end(); i++) {
Player* temp = *i;
cout << temp->print() << endl;
}
if (ss.size() == 1) {
return *ss.begin();
}
cout << "是否再通过 ID 查找?(Y / N):";
char confirm = 'N';
cin >> confirm;
if (confirm == 'Y' || confirm == 'y') {
int id = 0;
cout << endl << "请输入 ID:";
cin >> id;
return affirm_by_id(id);
}
else return NULL;
}
};
void changePlayer(){
show_all();
cout << "请输入要改变的选手 ID:";
int id = -1;
cin >> id;
cout << endl;
Player* player = affirm_by_id(id);
if (player == NULL) return;
cout << "请输入选手姓名:";
string name;
cin >> name;
player->set_name(name);
affirm_by_id(id);
};
void start_match(){
if (Player::players->size() < 12) {
cout << "人数不足!" << endl;
return;
}
system("cls");
cout << "展示本轮参赛选手:" << endl;
show_all();
cout << endl;
//write(0);
cout << "按任意键开始比赛" << endl;
system("pause");
system("cls");
Player::flush(round1(*Player::players));
//write(1);
cout << endl << "晋级选手是:" << endl;
show_all();
cout << endl;
cout << "下一轮比赛即将开始" << endl;
system("pause");
system("cls");
Player::flush(round2(*Player::players));
write();
cout << endl;
cout << "比赛的胜出者是:" << endl << endl;
set<Player*, Com>::const_iterator i = Player::players->begin();
Player* temp = *i;
i++;
cout << "★★·第一名:" << temp->print() << "·★★" << endl << endl;
temp = *i;
i++;
cout << "·☆·第二名:" << temp->print() << "·☆·" << endl << endl;
temp = *i;
i++;
cout << "···第三名:" << temp->print() << "···" << endl << endl;
system("pause");
Player::initial();
};
void write() {
if (Player::players->size() == 0) return;
ofstream ost;
ost.open("game_data.csv", ios::out | ios::app);
for (set<Player*>::const_iterator i = Player::players->begin(); i != Player::players->end(); i++) {
Player* temp = *i;
ost << temp->print() << endl;
}
ost << endl;
ost.close();
};
set<Player*, Com>& round1(set<Player*, Com>& p){
cout << "———————Round 1———————" << endl;
set<Player*, Com> team1;
set<Player*, Com> team2;
set<Player*, Com>* winner = new set<Player*, Com>;
set<Player*>::const_iterator it = p.begin();
for (int i = 0; it != p.end(); it++, i++) {
if (i == 0) {
cout << "······第一组······" << endl;
cout << "·ID\t姓名\t得分·" << endl;
}
else if (i == 6) {
cout << "······第二组······" << endl;
cout << "·ID\t姓名\t得分·" << endl;
}
Player* temp = *it;
temp->set_socre(socre());
cout << temp->print() << endl;
if (i < 6) team1.insert(temp);
else team2.insert(temp);
}
set<Player*, Com>::const_iterator i1 = team1.begin();
set<Player*, Com>::const_iterator i2 = team2.begin();
for (int i = 0; i < 3; i++) {
if (i1 != team1.end()) {
winner->insert(*i1);
i1++;
}
if (i2 != team2.end()) {
winner->insert(*i2);
i2++;
}
}
return *winner;
};
double socre(){
vector<int> ss;
for (int i = 0; i < 10; i++) {
ss.push_back(rand() % 101);
}
sort(ss.begin(), ss.end());
double socre = accumulate(++ss.begin(), --ss.end(), 0);
socre /= 8;
return socre;
};
set<Player*, Com>& round2(set<Player*, Com>& p){
set<Player*, Com>* winner = new set<Player*, Com>;
cout << "———————Round 2———————" << endl;
cout << "·ID\t姓名\t得分·" << endl;
for (set<Player*, Com>::const_iterator it = p.begin(); it != p.end(); it++) {
Player* temp = *it;
temp->set_socre(socre());
cout << temp->print() << endl;
winner->insert(temp);
}
set<Player*, Com>::const_iterator it = winner->begin();
it++;
it++;
it++;
winner->erase(it, winner->end());
return *winner;
};
void histroy(){
cout << "========= 历 史 记 录 =========" << endl;
ifstream ifs;
ifs.open("game_data.csv", ios::in);
if (!ifs.is_open()) {
cout << "当前没有比赛记录" << endl;
return;
}
char c;
ifs >> c;
if (ifs.eof()) {
cout << "当前没有比赛记录" << endl;
return;
}
ifs.putback(c);
int n = 0;
string data;
while (ifs >> data) {
if (n % 3 == 0) {
cout << endl;
if (n % 9 == 0) {
cout << endl << "———————第 " << (n / 9) + 1 << " 届演讲比赛———————" << endl;
cout << "·ID\t姓名\t得分·" << endl;
}
}
n++;
cout << data << '\t';
}
cout << endl << "——————————————————" << endl;
};
void clear_histroy(){
ofstream ost;
ost.open("game_data.csv", ios::out | ios::trunc);
ost.close();
};
void show_all() {
cout << "========= 选 手 信 息 =========" << endl;
cout << "·ID·\t-姓名-\t·成绩·" << endl;
for (set<Player*>::const_iterator i = Player::players->begin(); i != Player::players->end(); i++) {
Player* temp = *i;
cout << temp->print() << endl;
}
cout << "========= 展 示 完 毕 =========" << endl;
};
bool log_out(){
cout << "确定要退出吗?未保存的记录将会消失(Y / N):";
char affirm = 'N';
cin >> affirm;
return affirm == 'Y' || affirm == 'y';
};
<C++>12 项目:演讲比赛管理系统
https://i-melody.github.io/2022/05/21/C++/入门阶段/12 项目:演讲比赛管理系统/