C++狼人杀单机游戏
  • 板块灌水区
  • 楼主Elgo87
  • 当前回复58
  • 已保存回复58
  • 发布时间2021/8/6 13:55
  • 上次更新2023/11/4 11:50:08
查看原帖
C++狼人杀单机游戏
393864
Elgo87楼主2021/8/6 13:55

说明如下:

  • 最近花了半个多月做的 求赞勿喷
  • 因为刚做出来不久,Bug肯定还是有的,可以提出来改进
  • 此帖作者将持续发表更新版本,请持续关注
  • 游戏界面借鉴了NOI OpenJudge上一位大神的,但是代码未抄一字,请放心版权问题

关于游戏:

  • 投票中平票系统即将开放
  • 12人局警长角色设计中
  • 玩玩就行,请勿转载...

Code

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;

const int daytime=0,night=1;
int day=0, during_time=daytime, player_number, my_number;

HWND hwnd=GetForegroundWindow();//窗口定义

/*设置颜色*/
const int blue=0,yello=1,red=2,green=3,purple=4,white=5;//颜色常量 
void color(int c){
	switch(c)
	{
		case red:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);break;
		case green:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
		case yello:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN);break;
		case blue:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
		case white:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE);break;
		case purple:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_BLUE);break;
	}
}

/*控制光标在控制台的位置 */
void gotoxy(int x,int y)
{
	COORD position;
    position.X=x;
	position.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}

/*初始化窗口*/
void init_Show_Window(){
	system("mode con lines=60 cols=188");//全屏 
	ShowWindow(hwnd,SW_MAXIMIZE);//窗口最大化 
	DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
	DrawMenuBar(GetConsoleWindow());//删除×字符 
}

/*玩家类*/
const int nvwu=0,cunmin=1,yuyanjia=2,langren=3,lieren=4,shouwei=5,good=6,die=1,life=2;
class player{
public:
	int type;
	int die_or_life;
	int how(){
		return die_or_life;
	}
	int is_light;//是否已经公布 
	int killer;
};
player players[1000];

/*转换白天模式*/ 
void change_daytime(){
	during_time=daytime;
	day++;
}

/*转换黑夜模式*/
void change_night(){
	during_time=night;
}

int nnvwu=0,ncunmin=0,nyuyanjia=0,nlangren=0,nlieren=0,nshouwei=0;
int idxnvwu,idxshouwei,idxyuyanjia;
/*初始化人数*/
void init_players(){
	int idx_l1=800,idx_l2=800,idx_l3=800;
	my_number=rand()%player_number;
	for(int i=0;i<player_number;i++){
			
		players[i].die_or_life=life;
		int t;
		while(true){
			t=rand()%(player_number==10||player_number==11 ? 6:player_number==12 ? 7:5);
			if(t==0){
				if(nnvwu>=1)
					continue;
				else
				{
					nnvwu++;
					idxnvwu=i;
					break;
				}
			}
			if(t==3){
				if(nlangren>=3)
					continue;
				else
				{
					if(idx_l1==800) idx_l1=i;
					else if(idx_l2==800) idx_l2=i;
					else idx_l3=i;
					nlangren++;
					break;
				}
			}
			if(t==2){
				if(nyuyanjia>=1)
					continue;
				else
				{
					idxyuyanjia=i;
					nyuyanjia++;
					break;
				}
			}
			if(t==1||t==4){
				if(ncunmin>=(player_number-(player_number==12 ? 6:5)))
					continue;
				else
				{
					ncunmin++;
					break;
				}
			}
			if(t==5){
				if(nlieren>=1)
					continue;
				else
				{
					nlieren++;
					break;
				}
			}
			if(t==6){
				if(nshouwei>=1)
					continue;
				else
				{
					nshouwei++;
					idxshouwei=i;
					break;
				}
			}
		}
		players[i].type = (t==4 ? 1:t==5 ? 4:t==6 ? 5:t);
		players[i].killer=214;
		players[i].is_light=0;
	}
	players[my_number].is_light = 1;
	if(players[my_number].type==langren){
		players[idx_l1].is_light = 1;
		players[idx_l2].is_light = 1;		
		players[idx_l3].is_light = 1;		
	}
}

/*在屏幕上打印东西*/
void print(){
	gotoxy(0,0);
	cout<<"作者:洛谷393864";
	gotoxy(90,0);
	if(during_time==night)
		color(red);
	else
		color(blue);
	printf("第%d天 | ",day);
	if(during_time==night) cout<<"黑夜";
	else cout<<"白天";
	
	gotoxy(0,3);
	color(blue);
	cout<<" 我的号位:"<<my_number+1;
	for(int i=0;i<player_number;i++){
		gotoxy(i*8+1,4);
		color(blue);
		cout<<i+1<<"号位"; 
		gotoxy(i*8+1,5);
		if(players[i].how()==die){
			color(red);
			cout<<"死 亡";
		}else{
			color(green);
			cout<<"存 活";
		}
		gotoxy(i*8+1,6);
		color(blue);
		if(players[i].is_light){
			if(players[i].is_light==1){
				switch(players[i].type){
					case nvwu: cout<<"女 巫";break;
					case yuyanjia: cout<<"\b预言家";break;
					case cunmin: cout<<"村 民";break;
					case langren:cout<<"狼 人"; break;
					case lieren:cout<<"猎 人"; break; 
					case shouwei:cout<<"守 卫"; break;
				}				
			}else{
				cout<<"好人";
			}

		}else{
			cout<<"未知";
		}
	}
	
} 

/*判断是否结束,没结束返回0  好人胜利返回1  狼人胜利返回2   平局返回3*/
int is_end(){
	int die_bad=0;
	int die_people=0;
	int die_god=0;
	for(int i=0;i<player_number;i++){
		if((players[i].type == nvwu || players[i].type == yuyanjia)&&players[i].die_or_life==die)
			die_god++;
		if(players[i].type == langren && players[i].die_or_life==die)
			die_bad++;
		if(players[i].type == ncunmin && players[i].die_or_life==die)
			die_people++;
	}
	if((die_bad==die_people || die_bad==die_god)&&(die_bad>=nlangren))
		return 3;
	if(die_bad>=nlangren)
		return 1;
	if(die_people>=ncunmin||die_god>=(player_number>=10 ? 3:2))
		return 2;
	return 0;
}
/*b是否在Arr中*/
bool is_include(int arr[],int b,int l){
	for(int i=0;i<l;i++){
		if(arr[i]==b)
		 return true;
	}
	return false;
}

/*主函数*/
int main(){
	srand(time(NULL));
	init_Show_Window();
	color(green);
	cout<<"欢迎来到狼人杀游戏\t\t\t为了更好的游戏体验,请右键点击上方↑↑,点击\"属性\",点击\"字体\"栏目,将字体修改为宋体或新宋体,将字号改为20\n作者:洛谷393864\n请勿私自转载,违者依法追究法律责任  注:10 11 12人局开设猎人  12人局开设守卫\n______________________\n";
	cout<<"请输入玩家人数(8-12人):";
	cin>>player_number;
	while(player_number<8||player_number>12)
		{ cout<<"请重新输入!\n"; cin>>player_number; }
	system("cls");
	cout<<"初始化身份中,请稍等.";
	for(int i=0;i<6;i++){
		for(int j=0;j<12;j++){
			cout<<".";
			Sleep(50);
		}		
		cout<<"\b\b\b\b\b\b\b\b\b\b\b\b            \b\b\b\b\b\b\b\b\b\b\b\b";
	}
	system("cls");
			
	init_players();
	cout<<"我的号位:"<<my_number+1<<endl
		<<"我的身份:";
	switch(players[my_number].type){
		case nvwu: cout<<"女巫\n";break;
		case yuyanjia: cout<<"预言家\n";break;
		case cunmin: cout<<"村民\n";break;
		case langren:cout<<"狼人\n";break;	
		case lieren:cout<<"猎人\n"; break;	
		case shouwei:cout<<"守卫\n";break;
	}
	change_daytime();
	system("pause");
	system("cls");
	cout<<"游戏加载中.";int ppppp=rand()%3+2;
	for(int i=0;i<ppppp;i++){
		for(int j=0;j<6;j++){
			cout<<".";
			Sleep(rand()%100+150);
		}		
		cout<<"\b\b\b\b\b\b      \b\b\b\b\b\b";
	}	
	print();
	
	while(!is_end()){
		change_night();
		system("cls");
		print();	
		int langrensha=-1,nvwudu=-1,nvwujiu=-1,shouweishou=-1;
		gotoxy(0,7);
		cout<<"________________________";
		gotoxy(0,8);
		color(white);
		cout<<"天黑~请闭眼~~~\n";
		Sleep(1500); 
		if(player_number==12){
			/*守卫部分*/
			color(blue);
			cout<<"守卫~请睁眼~~\n";
			Sleep(1500);
			cout<<"你要守护的是?\n";
			if(players[my_number].type==shouwei&&players[my_number].die_or_life == life){
				cin>>shouweishou;
				while(!(shouweishou>=1&&shouweishou<=player_number&&players[shouweishou-1].die_or_life == life)){
					cout<<"请重新输入!\n";
					cin>>shouweishou;
				}
				cout<<"你今晚要守护的是"<<shouweishou<<"号\n";
				Sleep(1500); 
				shouweishou--;
			}else{
				if(players[idxshouwei].die_or_life == life){
					shouweishou=rand()%10;
					while(!(shouweishou>=1&&shouweishou<=player_number&&players[shouweishou-1].die_or_life == life)){
						shouweishou=rand()%10;
					}
				}
			}		
			Sleep(2000);
			cout<<"守卫请闭眼"<<endl<<endl;
			Sleep(2000);
		} 

		
		/*狼人部分*/
		color(red);
		cout<<"狼人~请睁眼~~~\n";
		Sleep(1500);
		cout<<"你们今晚要杀~谁~~??\n";
		if(players[my_number].type==langren&&players[my_number].die_or_life == life){
			cin>>langrensha;
			while(!(langrensha>=1&&langrensha<=player_number&&players[langrensha-1].die_or_life==life)){
				cout<<"请重新输入!\n";
				cin>>langrensha;
			}
			cout<<"你们今晚要杀的是"<<langrensha--<<"号\n";
			Sleep(3500);
		}else{
			while(langrensha==-1 || players[langrensha].die_or_life == die){
				langrensha=rand()%player_number;
			}
			Sleep(3000);
		}
		cout<<"狼人请~闭眼~~\n\n";
		Sleep(3500);
		/*女巫部分*/ 
		color(purple);
		cout<<"女巫~~请睁眼~~\n";
		if(players[my_number].type==nvwu&&players[my_number].die_or_life == life){
			Sleep(2000);
			cout<<"今晚"<<langrensha+1<<"号死了,你想用解药吗?(1想 / 2不想)\n";
			int is_nvwujie=0;
			cin>>is_nvwujie;
			while(is_nvwujie!=1&&is_nvwujie!=2){
				cout<<"请重新输入\n";
				cin>>is_nvwujie;
			} 
			if(is_nvwujie==1) {
				Sleep(1000);
				cout<<"已经解救"<<langrensha+1<<"号\n";
				nvwujiu=langrensha;
			}
			Sleep(1500);
			cout<<"你想用毒药吗?(1想 / 2不想)\n";
			Sleep(1500);
			int is_nvwudu=0;
			cin>>is_nvwudu;
			while(is_nvwudu!=1&&is_nvwudu!=2){
				cout<<"请重新输入\n";
				cin>>is_nvwudu;
			} 		
			if(is_nvwudu==1){
				Sleep(1500);
				cout<<"你想毒谁?\n"; 
				cin>>nvwudu;
				while(!(nvwudu>=1&&nvwudu<=player_number&&players[nvwudu].die_or_life==life)){
					cout<<"请重新输入\n";
					cin>>nvwudu; 
				}
				nvwudu--;
				Sleep(1500);
				cout<<"已经毒死了"<<nvwudu+1<<"号\n";
			}					
		}else{
			if(players[idxnvwu].die_or_life == life){
				int is_jiu=rand()%8;
				if(is_jiu==0){
					nvwujiu=langrensha;
				}
				int is_du=rand()%4;
				if(is_du==0){
					int num=rand()%player_number;
					nvwudu=num;
				}				
			}

		} 
		Sleep(3000);
		cout<<"女巫~请闭眼~~\n\n";
		/*预言家部分*/
		Sleep(1500);
		color(green);
		cout<<"预言家~请睁眼~~\n";
		Sleep(2000);
		if(players[my_number].type==yuyanjia&&players[my_number].die_or_life == life){
			cout<<"请问你想查验谁的身份\n";
			int p;
			cin>>p;
			while(!(p>=1&&p<=player_number)){
				cout<<"请重新输入!\n";
				cin>>p;
			}
			Sleep(2000);
			cout<<p<<"号的身份是——";
			Sleep(1000);
			if(players[p-1].type == langren){
				cout<<"狼人\n";
				players[p-1].is_light = 1;
			}else{
				cout<<"好人\n";
				players[p-1].is_light = 2;
			}
		}
		cout<<"预言家~~请闭眼~~\n";
		Sleep(2000);
		change_daytime(); 
		system("cls");
		print(); 
		gotoxy(0,7);
		cout<<"________________________\n";
		Sleep(3000);
		color(white);
		cout<<"天亮了\n";
		Sleep(2000);
		gotoxy(0,9);
		cout<<"昨晚";
		bool is_die_lieren=false;
		int idx_lieren=-1;
		if(langrensha==nvwujiu||langrensha==shouweishou){
			if(nvwudu!=-1){
				cout<<nvwudu+1<<"号"<<"死了\n";
				players[nvwudu].killer = nvwu;
				players[nvwudu].die_or_life = die;
				if(players[nvwudu].type == lieren){
					is_die_lieren=true;
					idx_lieren=nvwudu;
				} 
			}
			else
				cout<<"是平安夜\n";
		}else{
			cout<<langrensha+1<<"号";
			if(nvwudu!=langrensha&&nvwudu!=-1){
				if(shouweishou==nvwudu) 
					goto PPP1;
				cout<<"和"<<nvwudu+1<<"号";
				players[nvwudu].die_or_life = die;
				players[nvwudu].killer = nvwu;
				if(players[nvwudu].type == lieren){
					is_die_lieren=true;
					idx_lieren=nvwudu;
				}
			} 
			PPP1:
				cout<<"死了\n";
			players[langrensha].die_or_life = die;
			players[langrensha].killer = langren;
			if(players[langrensha].type == lieren){
				is_die_lieren=true;
				idx_lieren=langrensha;
			}
		}
		Sleep(2000);
		int lierendai=-1;
		if(is_die_lieren){
			cout<<idx_lieren+1<<"号是猎人\n";

			players[idx_lieren].is_light = 1;
			Sleep(1000);
			if(idx_lieren==my_number){
				cout<<"你想带走几号?\n";
				cin>>lierendai;
				while(!(lierendai>=1&&lierendai<=player_number&&players[lierendai].die_or_life==life)){
					cout<<"请重新输入!\n";
					cin>>lierendai;
				}
				lierendai--;
			}else{
				lierendai=rand()%player_number;
				while(players[lierendai].die_or_life == die){
					lierendai=rand()%player_number;
				}
			}
			Sleep(2000);
			cout<<"猎人选择带走"<<lierendai+1<<"号\n";
			Sleep(2000);
			players[lierendai].die_or_life = die;
		}
		system("cls");
		print();
		
		int tong[100]={0},cannot[100]={0}; memset(cannot,-1,sizeof(cannot));
		gotoxy(0,7);
		color(blue);
		cout<<"________________________\n";
		color(white);
		cout<<"下面进入投票环节\n";
		Sleep(2000);
		TOUPIAO:
		for(int i=0;i<player_number;i++){
			if(players[i].die_or_life == life&&!is_include(cannot,i,player_number)){
				if(i==my_number){
					cout<<"你要投几号?\n";
					int n;
					cin>>n;
					while(!(n>=1&&n<=player_number&&!is_include(cannot,n-1,player_number))){
						cout<<"请重新输入!\n";
						cin>>n;
					}
					Sleep(2000);
					cout<<setw(2)<<my_number+1<<"号投了"<<setw(2)<<n<<"号\n";
					tong[n-1]++;
				}else{
					int t=-1;
					while(t==-1 || players[t].die_or_life == die || t==i){
						t=rand()%player_number;
					}
					cout<<setw(2)<<i+1<<"号"<<"投了"<<setw(2)<<t+1<<"号\n";
					tong[t]++;
				}
				
				Sleep(rand()%1000+1000);
			}
		}
		int idx_max=-1,maxn=-1;
		for(int i=0;i<player_number;i++)
			if(maxn<tong[i])
			{
				maxn=tong[i];
				idx_max=i;
			}
		cout<<idx_max+1<<"号有"<<maxn<<"张票,出局\n";
		Sleep(4000);
		players[idx_max].die_or_life = die;
		players[idx_max].killer = good;
		lierendai=-1;
		if(players[idx_max].type==lieren){
			cout<<idx_max+1<<"号是猎人\n";
			players[idx_max].is_light = 1;
			Sleep(1000);
			if(idx_max==my_number){
				cout<<"你想带走几号?\n";
				cin>>lierendai;
				while(!(lierendai>=1&&lierendai<=player_number)){
					cout<<"请重新输入!\n";
					cin>>lierendai;
				}
				lierendai--;
			}else{
				lierendai=rand()%player_number;
				while(players[lierendai].die_or_life == die){
					lierendai=rand()%player_number;
				}
			}
			Sleep(2000);
			cout<<"猎人选择带走"<<lierendai+1<<"号\n";
			Sleep(2000);
			players[lierendai].killer = lieren;
			players[lierendai].die_or_life = die;
		}
		system("cls");
		print(); 
		
	}
	
	system("cls");
	switch(is_end()){
		case 1:cout<<"好人胜利\n\n"; break;
		case 2:cout<<"狼人胜利\n\n"; break;
		case 3:cout<<"本局平局\n\n"; break;
	}
	for(int i=0;i<player_number;i++){
		cout<<i+1<<"号位:\t";
		switch(players[i].type){
			case nvwu: cout<<"女巫\t";break;
			case yuyanjia: cout<<"预言家\t";break;
			case cunmin: cout<<"村民\t";break;
			case langren:cout<<"狼人\t";break;
			case lieren:cout<<"猎人\t"; break;	
			case shouwei:cout<<"守卫\t";break;	
		} 
		cout<<"最终";
		switch(players[i].killer){
			case nvwu:cout<<"被女巫毒死\n"; break;
			case langren:cout<<"被狼人杀死\n"; break;
			case good:cout<<"被投票出局\n"; break;
			case lieren:cout<<"被猎人带走\n";break;
			default :cout<<"存活\n";
		}
		cout<<endl;
	}
	system("pause");
	return 0;
}

最后附上一句

本人Coding不易,不喜勿喷!

2021/8/6 13:55
加载中...