#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<sstream>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<string>
#include<time.h>
#include<fstream>
#include<sstream>
#include<windows.h>
#include<conio.h>
#include<cctype>
using namespace std;
char *name[15] = {"ZhaoYun","GongBenWuZang","Kai","BaiQi","HanXing","ZhuGeLiang","LiuBang","HouYi","WangZhaoJun","DaJi","AnQiLa","DiaoChan","LuNa","BuZhiHuoWu","ChaiWenJI"};//保存相应编号的英雄名
void FullScreen(){ //黑框全屏
HWND hwnd=GetForegroundWindow();
int x=GetSystemMetrics(SM_CXSCREEN)+300;
int y=GetSystemMetrics(SM_CYSCREEN)+300;
char setting[30];
sprintf(setting,"mode con:cols=%d lines=%d",x,y);
system(setting);
SetWindowPos(hwnd,HWND_TOPMOST,0,0,x+300,y+300,NULL);
MoveWindow(hwnd,-10,-40,x+300,y+300,1);
printf("\n\n");
}
void input(); //输入界面
void battle(); //战斗界面
void Renew_Data(); //更新用户和英雄数据
void Quit();//退出程序
void Read_Heros();//读取英雄数据
int trans(string s);//将字符串转化为数字,如不是数字则返回-1
void Read_Users(); //读取用户数据
void welcome();//欢迎界面
void goodbye();//再见界面
int select(){//取[0,2]范围内的随机数
return rand()%3;
}
FILE *f_heros; //用于输出和读取英雄数据
fstream fs; //用于读取用户数据
ofstream ofs; //用于输出用户数据
multiset<int> choose; //用于保存用户所选的3个英雄编号
struct Hero
{
int id; //英雄编号
int weapon[3];//英雄技能数目
int win;//英雄胜利场数
int tot; //英雄参战场数
}hero[15];
struct User
{
string User_Name;//用户名
string Secret;//用户密码
int WinNumber;//用户胜利场数
int tot;//用户参战场数
User(string name,string secret,int num,int t):User_Name(name),Secret(secret),WinNumber(num),tot(t){};
User(){};
}User_Temp;//当前登陆用户
typedef pair<string,User> PAIR;
struct Rank{//制度用户排名规则
bool operator()(const PAIR & p1,const PAIR & p2){
if(p1.second.WinNumber==0) return false;//用户还未战斗过则需特殊考虑
if(p2.second.WinNumber==0) return true;//用户还未战斗过则需特殊考虑
return (p1.second.WinNumber*1.0/p1.second.tot)>(p2.second.WinNumber*1.0/p2.second.tot);
}
};
bool cmp(const struct Hero h1,const struct Hero h2){//制定英雄排名规则
if(h1.win==0) return false;//英雄还未战斗过则需特殊考虑
if(h2.win==0) return true;//英雄还未战斗过则需特殊考虑
return double(h1.win*1.0/h1.tot)>double(h2.win*1.0/h2.tot);
}
map<string,User> User_Data;//保存从文件读取的用户数据
int main(){
FullScreen();
srand((int)time(0)); //取随机种子
welcome();
f_heros = fopen("hero_note.txt","r+");
Read_Heros();
input();
Renew_Data();
return 0;
}
void Read_Users(){
User_Data.clear();
string line;//用于保存一行数据
fs.open("user_note.txt",ios::in);
while(getline(fs, line)) { //每一次读取一个用户的所有信息
int k = 0;
line += '\n';
istringstream iss(line);
string t[4];
while(iss>>t[k++]){}
User_Data[t[0]] = User(t[0],t[1],trans(t[2]),trans(t[3]));
}
fs.close();
}
void Read_Heros(){
int i=0;
while(fscanf(f_heros,"%d%d%d%d%d%d",&hero[i].id,&hero[i].weapon[0],
&hero[i].weapon[1],&hero[i].weapon[2],&hero[i].win,&hero[i].tot)!=EOF){ //每一次读一个英雄信息
i++;
}
}
void input(){
printf("登陆 请按 1 | 注册 请按 2 | 查询 请按 3 | 按其余任意键 退出 : ");
Read_Users();
string temp; //读取用户输入数据
cin>>temp;
if(temp!="1"&&temp!="2"&&temp!="3"){
printf("???????\n");
Quit();
}
else if(temp=="1"){
printf("请输入用户名: ");
string U_N,Code;
cin>>U_N;//保存用户输入的用户名
getline(cin,Code); //读回车
if(!User_Data.count(U_N)){
printf("无该用户名!\n");
input();
}
while(1){
printf("请输入密码:");
getline(cin,Code);
if(User_Data[U_N].Secret != Code){
printf("密码错误!\n");
printf("重新输入 请按 1|按其余任意键退出 : ");
string t;
cin>>t; //读取用户输入数据
getline(cin,Code);//读回车
if(t!="1") Quit();
else continue;
}else{
User_Temp = User_Data[U_N];
printf("欢迎您!");
cout<<User_Temp.User_Name<<" ~(o(^?^)o)~ "<<endl;
break;
}
}
battle();
}
else if(temp=="2"){
int yes_ = 1;
string temp_code,code,n;
struct User New_Player;
while(yes_){
printf("请输入用户名(用户名长度不应长于15,且不应含有空格!) : ");
getline(cin,New_Player.User_Name);//读回车
getline(cin,New_Player.User_Name);
if(New_Player.User_Name.size()>15) { //用户名长度是否超过15
printf("该用户名超过限定长度!\n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
continue;
}
if(New_Player.User_Name.size()==0){ //用户是否直接输入回车
printf("该用户名不合规定 ! \n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
continue;
}
if(New_Player.User_Name.find(" ")!=string::npos) { //用户名中是否含有空格
printf("用户名中有空格!\n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
continue;
}
if(User_Data.count(New_Player.User_Name)){ //用户名是否重复
printf("该用户名已存在!");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
continue;
}
break;
}
yes_ = 1;
while(yes_){
string n;
printf("请输入密码(密码中请不要夹带空格!):"); //密码中是否含有空格
getline(cin,code);
if(code.find(" ")!=string::npos) {
printf("密码中有空格!\n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
}
if(code.size()==0){ //用户是否直接输入回车
printf("该密码不合规定 ! \n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
continue;
}
if(n=="1") continue;
printf("请再次输入密码确认:");
getline(cin,temp_code);
if(code!=temp_code){ //两次密码是否一致
printf("两次密码不一样!\n");
printf("重新输入 请按 1 |按其余任意键退出 : ");
cin>>n;
if(n!="1") Quit();
else if(n=="1"){
getline(cin,code); //读回车
continue;
}
}
else{//创立新用户
yes_ = 0;
New_Player.Secret = code;
New_Player.WinNumber = 0;
New_Player.tot = 0;
User_Data[New_Player.User_Name] = New_Player;
}
}
Renew_Data(); //更新数据
input();//回到开始登陆界面
}
else if(temp=="3"){
int temp;
printf("查询 用户信息 请按 0 | 查询 英雄信息 请按 1 : ");
cin>>temp;
if(temp==0){
int rank = 1;
vector<PAIR> user_rank(User_Data.begin(),User_Data.end()); //将map中的用户数据读入vector中来排序
sort(user_rank.begin(),user_rank.end(),Rank());//用户排序
for(rank = 0;rank!=user_rank.size();rank++){
printf("第%2d名: ",rank+1);
string T = user_rank[rank].first;
if(T.size()<15) T.insert(T.size(),15-T.size(),' '); //为保证整齐输出,将用户名长度未到15的用户名补到15的长度
cout<<T;
if(user_rank[rank].second.tot==0) printf("胜率: 0.00%%\n");//用户还未战斗过则需特殊考虑
else printf("胜率: %5.2f%%\n",(user_rank[rank].second.WinNumber*1.0/user_rank[rank].second.tot)*100);
}
}
if(temp==1){
struct Hero temp[15];
memcpy(temp,hero,sizeof(struct Hero)*15); //临时将英雄数据复制到temp中排序,避免原hero[i]中的英雄对应数组下标改变
sort(temp,temp+15,cmp);//英雄排序
for(int i = 0;i<15;i++){
if(temp[i].tot==0) printf("胜率: 0.00%%\n");//英雄还未战斗过则需特殊考虑
printf("第%-2d名: %-15s 胜率: %5.2f%%\n",i+1,name[temp[i].id],(temp[i].win*1.0/temp[i].tot)*100);
}
}
input();//回到开始登陆界面
}
}
void battle(){
printf("请输入三个您选择的英雄编号: ");
choose.clear();
struct Hero user_hero[3],hostile[3]; //用于保存用户和敌人分别所选择的三个英雄
int user_hero_select[3],u_id[3],h_id[3];
for(int i = 1;i<=3;i++){
cin>>user_hero_select[i];
if(user_hero_select[i]>=15||user_hero_select[i]<0){
printf("该英雄不存在!请重新输入!\n");
i--;
}
else{
choose.insert(user_hero_select[i]);
user_hero[i] = hero[user_hero_select[i]];
u_id[i] = user_hero_select[i];//保存用户选择的英雄编号
}
}
for(int i = 0;i<3;i++){//敌人随机选择英雄
int t = rand()%15;
hostile[i] = hero[t];
h_id[i] = t;
}
int x,y;
int win_num1 = 0,win_num2 = 0;//保存用户和敌人在9局中分别胜利的场数
for(int i = 1;i<=9;i++){
struct Hero h1,h2;
int _0_1 = 0,_0_2 = 0,has_input = 0;//0_1_,_0_2分别指用户,敌人当前英雄是否可用技能是否为0. has_input指代用户是否输入了数据
y = select();//敌人选择出战英雄
printf("敌人选择了%s出战! 您现在有3秒选择出战英雄!\n",name[h_id[y]]);
printf("请输入您选择出战的英雄编号 %d - %s | %d - %s | %d - %s :",user_hero_select[0],name[user_hero_select[0]],user_hero_select[1],name[user_hero_select[1]],user_hero_select[2],name[user_hero_select[2]]);
time_t Time = time(0);//开始计时
string ch; //保存用户输入
Time += 3;//用户有3秒时间考虑
while(Time>time(0)){
if (kbhit()){//检测用户是否输入数据
cin>>ch;
if (ch == "\n"){
break;
}else has_input = 1;//用户已输入
}
}
if(has_input) x = trans(ch); //获取用户选择英雄编号
else if(!has_input){
x = select();
printf("\n您已超时 ! 系统已自动为您选择了编号为%d号的%s英雄出战\n",user_hero_select[x],name[user_hero_select[x]]);
}
if(!choose.count(x)&&has_input){
x = select();//用户输入数据不符合规定
printf("英雄编号错误!系统已自动为您选择了编号为%d号的%s英雄出战\n",user_hero_select[x],name[user_hero_select[x]]);
}
h1 = hero[x];h2 = hostile[y];//h1,h2分别指用户和敌人的出战英雄
int attack_user,attack_host;//用户和敌人英雄选择使用的技能
attack_user = select();attack_host = select();
while(h1.weapon[attack_user]==0) { //用户英雄选出可用的技能
attack_user = select();
int k;
for(k = 0;k<=2;k++) if(h1.weapon[k]!=0) break;
if(k==3){
_0_1 = 1;
break;
}
}
while(h2.weapon[attack_host]==0) {//敌人英雄选出可用的技能
attack_host = select();
int k;
for(k = 0;k<=2;k++) if(h2.weapon[k]!=0) break;
if(k==3){
_0_2 = 1;
break;
}
}
int user = x,host = h_id[y]; //用户英雄编号 和 敌人英雄编号
hero[host].tot++; //用户英雄参战数目加1
hero[user].tot++; //敌人英雄参战数目加1
cout<<endl;
if(_0_1==1&&_0_2==1) continue; //双方英雄都无技能可用则平局
else if(_0_1==1&&_0_2==0){win_num2++;continue;} //用户英雄无技能可用,但敌人英雄有技能可用,则敌人英雄胜利
else if(_0_1==0&&_0_2==1){win_num1++;continue;} //敌人英雄无技能可用,但用户英雄有技能可用,则敌人英雄胜利
if(attack_user==attack_host){h2.weapon[attack_user]--;h1.weapon[attack_user]--;continue;} //平局
if(attack_user==0&&attack_host==1){win_num2++;hero[host].win++;h2.weapon[1]--;h1.weapon[0]--;}
if(attack_user==0&&attack_host==2){win_num1++;hero[user].win++;h2.weapon[2]--;h1.weapon[0]--;}
if(attack_user==1&&attack_host==0){win_num1++;hero[user].win++;h2.weapon[0]--;h1.weapon[1]--;}
if(attack_user==1&&attack_host==2){win_num2++;hero[host].win++;h2.weapon[2]--;h1.weapon[1]--;}
if(attack_user==2&&attack_host==0){win_num2++;hero[host].win++;h2.weapon[0]--;h1.weapon[2]--;}
if(attack_user==2&&attack_host==1){win_num1++;hero[user].win++;h2.weapon[1]--;h1.weapon[2]--;}
}
printf("User Win Number %d\n",win_num1);
printf("Computer Win Number %d\n",win_num2);
User_Data[User_Temp.User_Name].tot++;
if(win_num1>win_num2){
printf("You Win!!!!!!!!!!!!!!!!!!!!!!!\n");
User_Data[User_Temp.User_Name].WinNumber++;
}
else if(win_num1<win_num2){
printf("You Lose!!!!!!!!!!!!!!!!!!!!!\n");
}else printf("Not Win,Not Lose\n");
Renew_Data();//更新数据
input();//返回开始界面
}
void Renew_Data(){
ofs.open("user_note.txt",ios::out);
rewind(f_heros);
for(map<string,User>::iterator it = User_Data.begin();it != User_Data.end(); ++it){
ofs<<it->first<<" "<<(it->second).Secret<<" "<<(it->second).WinNumber<<" "<<(it->second).tot<<endl;
}
cout<<endl;
for(int i = 0;i<15;i++){
fprintf(f_heros,"%d %d %d %d %d %d\n",hero[i].id,hero[i].weapon[0],hero[i].weapon[1],hero[i].weapon[2],hero[i].win,hero[i].tot);
}
ofs.close();
}
void Quit(){
Renew_Data();
ofs.close();
fclose(f_heros);
goodbye();
exit(0);
}
int trans(string s){
int num = 0;
for(int i = 0;i<s.size();i++){
if(!isdigit(s[i])) return -1;//如非数字字符返回-1
num = num*10 + s[i]-'0';
}
return num;
}
void welcome(){
printf("欢迎来到:\n");
fstream wel;//欢迎文件
wel.open("glory.txt",ios::in);
string line;//用于保存一行数据
if(!wel) {
return;
}
while(getline(wel, line)) {
line += '\n';
cout<<line<<endl;
}
wel.close();
}
void goodbye(){
fstream bye; //再见文件
bye.open("byebye.txt",ios::in);
string line;//用于保存一行数据
if(!bye) {
return;
}
while(getline(bye, line)) {
line += '\n';
cout<<line<<endl;
}
bye.close();
}
王者农药 - 程序实习周作业
最新推荐文章于 2022-08-14 18:22:05 发布