用Java写了一个简单的控制台狼人杀游戏
最近上课老师布置的作业是写一个简答的狼人杀游戏,花了大概两天不到写完,比较乱,还有很多逻辑不太顺的地方,有问题的欢迎讨论。
先搞清楚游戏的玩法:
12人局的一个游戏
平民阵营(好人阵营):4个平民
神职阵营(好人阵营):4个,分别是预言家,女巫,猎人,白痴
狼人阵营(狼人阵营):4个,4个狼人
2个大的阶段:黑夜阶段,白天阶段
黑夜阶段:(第一阶段)
4个狼人见面,共同去决定猎杀一名玩家,狼人的行为就结束了
神职阵营行动:
1.预言家行动:预言家会查验一个玩家的身份是好人还是狼人
查验3号,3号身份--女巫,查验的结果为好人,查验4号,4号身份--狼人,查验的结果就是狼人。
2.女巫:一局游戏一共有两瓶药,分别解药与毒药。当女巫有解药的时候,会告诉当天晚上谁被狼人袭击了,决定是否救这名玩家。一旦解药被使用,就无法得知谁被杀了。在解药没有任何操作的时候,进行毒药的操作,选择一名玩家的序号,直接毒杀。一旦两瓶药都用完,晚上无任何操作。
女巫两瓶药都在,4号被猎杀了,提示:今晚4号死了,是否使用解药?1.救 2不救
1 -->今天晚上女巫环节就结束了 2-->是否使用毒药?(给定序号) 10 -->10,4两个都死了
3.猎人:晚上无任何行动。当晚上他被狼人猎杀、放逐的时候,白天宣布死亡的那刻,他可以发动技能开枪带走一名玩家
4.白痴:晚上无任何行动。当白天公投阶段被放逐出时,可以发动技能免除放逐。
平民阵营:无任何行动。
白天阶段:(第二阶段)
1.宣布死讯:公布死亡的玩家序号(不公布其身份),死亡的玩家发表遗言
2.随机指定剩下存活的人的序号,开始发言(3号发言之后,5号发言,6号...)
3.当所有人都发言完毕时候,所有玩家公投一名玩家进行放逐(死亡),如果他的身份是猎人或白痴的话,会发动技能(猎人是带走一名玩家,白痴免疫此次放逐)
黑夜-->白天-->交替进行 直到每个阶段阶段结束后,进行胜负判定
胜负判定:
当其中一方阵营全部死亡,即另一方阵营获胜。
好人获胜:4名狼人全都死了
狼人获胜:4个神职死亡 或者 4个平民死亡 都算狼人获胜
直接上代码:
package Role;//包名自己随便起
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Menu {
String identity[]= {"平民","狼人","平民","预言家","狼人","平民","狼人","女巫","平民","白痴","狼人","猎人"};
List<String> role=new ArrayList<String>();
//用于女巫用药的判断
int arr[]= {0,0};
boolean antidote=true;//解药
Boolean poison=true;//毒药
Scanner scanner=new Scanner(System.in);
//进入
public void into() {
System.out.println("----------欢迎进入狼人杀游戏!----------");
while(true) {
System.out.println("请选择您的操作: 1.开始游戏 2.退出");
int choice=Integer.valueOf(scanner.nextLine());
switch(choice) {
case 1:
allocation();//角色分配
start();//开始游戏
case 2:
break;
default:
continue;
}
}
}
//开始游戏
private void start() {
// TODO Auto-generated method stub
while(true) {
int d=0;//死亡人数统计
//夜间行动
System.out.println("----------天黑请闭眼,狼人请杀人!---------");
System.out.println("-----------------狼人回合-----------------");
System.out.println("狼人请输入要猎杀的玩家:");
int index=Integer.valueOf(scanner.nextLine());
String r=role.get(index-1);
d++;
//女巫行为,若使用毒药,arr[1]为毒杀玩家编号,使用解药则arr[0]=1,都不使用则均为0
witch(index);
if(arr[0]==1) {
role.add(index-1, r);//重新加到list中
d--;
}
if(arr[1]!=0) {//使用毒药
if(role.contains("预言家")) {//预言家未死
prophet();//预言家行为
}
d++;
}
//判断游戏是否结束
if(isEnding()) break;
prophet();//预言家行为
//白天行动
System.out.println("-------------天亮了-------------");
if(d!=0) {//有人死了
System.out.println("--------昨晚有"+d+"人死了!--------");
toSpeak(index,arr[1],d);//玩家发言
vote();//公投阶段
if(isEnding()) break;
showPlayer();
continue;
}else {
System.out.println("----------今晚是平安夜!----------");
toSpeak(index,arr[1],d);
vote();//公投阶段
if(isEnding()) break;
showPlayer();
continue;
}
}
}
//公投阶段
private void vote() {
// TODO Auto-generated method stub
System.out.println("请投票选出一位玩家结束游戏:");
int choice=Integer.valueOf(scanner.nextLine());
//判断公投玩家是否是猎人
if(role.get(choice-1).endsWith("猎人")) {
hunter();//猎人行为
role.set(choice-1,"");
}
//公投玩家为白痴
else if(role.get(choice-1).endsWith("白痴")){
idiot(choice-1);//白痴行为
}else {
role.set(choice-1,"");
}
}
//猎人行为
private void hunter() {
// TODO Auto-generated method stub
System.out.println("-----------------猎人回合-----------------");
System.out.println("是否要猎杀一名玩家? 1.是 2.否");
int choice=Integer.valueOf(scanner.nextLine());
if(choice==1) {
System.out.println("请输入要猎杀的玩家:");
int num=Integer.valueOf(scanner.nextLine());
if(role.get(num-1).endsWith("白痴")) {
idiot(num);
return;
}else {
System.out.println("死亡玩家发表遗言:");
System.out.println("玩家"+num+":");
String talk=scanner.nextLine();
role.set(num-1,"");
}
}
}
//白痴行为
private void idiot(int i) {
// TODO Auto-generated method stub
System.out.println("-----------------白痴回合-----------------");
System.out.println("是否免疫此次放逐? 1.是 2.否");
int choice=Integer.valueOf(scanner.nextLine());
if(choice==1) {
return;
}else {
System.out.println("死亡玩家发表遗言:");
System.out.println("玩家"+i+":");
String talk=scanner.nextLine();
role.set(i-1,"");//删除白痴玩家
}
}
//玩家发言
private void toSpeak(int index, int k,int d) {
// TODO Auto-generated method stub
String talk;
if(d!=0) {
System.out.println("死亡玩家发表遗言:");
//狼人所杀玩家
System.out.println("玩家"+index+":");
talk=scanner.nextLine();
role.set(index-1,"");//将被杀的玩家移除
//毒药所杀玩家
if(k!=0) {//使用了毒药
System.out.println("玩家"+k+":");
talk=scanner.nextLine();
role.set(k-1,"");
}
}
System.out.println("剩余玩家开始发言:");
int random=1+(int)(Math.random()*(role.size()-1));//取随机数
for(int i=random;i<role.size();i++) {
if(role.get(i).equals("")) continue;
System.out.println("玩家"+(i+1)+":");
talk=scanner.nextLine();
}
for(int i=0;i<random;i++) {
if(role.get(i).equals("")) continue;
System.out.println("玩家"+(i+1)+":");
talk=scanner.nextLine();
}
}
//遍历显示当前存活玩家
private void showPlayer() {
// TODO Auto-generated method stub
System.out.println("目前身份:");
for(String s:role){
if(s.equals("")) continue;
System.out.println(s);
}
System.out.println("-----------------------------------------");
System.out.println();
}
//预言家行为
private void prophet() {
// TODO Auto-generated method stub
System.out.println("-----------------预言家回合-----------------");
System.out.println("是否查验一名玩家身份? 1.是 2.否");
int choice=Integer.valueOf(scanner.nextLine());
if(choice==1) {
System.out.println("请选择要查验的玩家:");
int index=Integer.valueOf(scanner.nextLine());
if(role.get(index-1).endsWith("狼人")) {//是狼人
System.out.println("玩家"+index+"是狼人");
}else {
System.out.println("玩家"+index+"是好人");
}
}else {
return;
}
}
//女巫行为
private void witch(int index) {
// TODO Auto-generated method stub
boolean flag=true;//是否使用药剂,使用则为false
System.out.println("-----------------女巫回合-----------------");
System.out.println("被杀的是玩家"+index);
//还有解药能够使用
if(antidote) {
System.out.println("是否对玩家"+index+"选择使用解药? 1.使用 2.不使用");
int choice1=Integer.valueOf(scanner.nextLine());
if(choice1==1) {//输入除1以外的内容均视为不使用解药
flag=false;
antidote=false;//解药不可再次使用
arr[0]=1;
return;
}
}
//还有毒药能够使用且未使用解药
if(poison&&flag) {
System.out.println("是否选择使用毒药? 1.使用 2.不使用");
int choice2=Integer.valueOf(scanner.nextLine());
if(choice2==1) {//输入除1以外的内容均视为不使用毒药
System.out.println("请选择使用毒药的玩家:");
int num=Integer.valueOf(scanner.nextLine());
poison=false;//毒药不可再次使用
arr[1]=num;
}
}
}
//游戏结束判定
private boolean isEnding() {
// TODO Auto-generated method stub
int priest=0;//神职人员
int civilians=0;//平民
int werewolf=0;//狼人
for(int i=0;i<role.size();i++) {
String s=role.get(i);
if(s.endsWith("女巫")||s.endsWith("预言家")
||s.endsWith("猎人")||s.endsWith("白痴")) {
priest++;
}else if(s.endsWith("平民")) {
civilians++;
}else if(s.endsWith("狼人")) {
werewolf++;
}
}
//无神职人员或平民存活,狼人获胜
if(priest==0||civilians==0) {
System.out.println("游戏结束,恭喜狼人获得胜利!");
return true;
}else if(werewolf==0) {//无狼人存活,好人获胜
System.out.println("游戏结束,恭喜狼人获得胜利!");
return true;
}else {//游戏未结束
return false;
}
}
/* * 每次从已知数组随机一个数,然后将数组的最后一个值 赋值给前面随机到的数的位置上,
* 然后将长度-1,再从原数组下标-1的数组中随机。 运算次数就是数组长度.
*/
//角色分配
private void allocation() {
// TODO Auto-generated method stub
int count = identity.length;
int cbRandCount = 0;// 索引
int cbPosition = 0;// 位置
int i=0;
do {
Random rand = new Random();
int r = count - cbRandCount;
cbPosition = rand.nextInt(r);
role.add(i++, i+identity[cbPosition]);
cbRandCount++;
identity[cbPosition] = identity[r - 1];// 将最后一位数值赋值给已经被使用的cbPosition
}while(cbRandCount <count);
System.out.println("玩家所分配到的角色如下:");
for(String s:role) {
System.out.println("玩家"+s);
}
}
}
主函数调用一下
package Role;
public class Main {
public static void main(String args[]) {
Menu menu=new Menu();
menu.into();
}
}
运行结果:

还有些功能没有实现,比如说已经死亡的玩家在狼人行动和公投时就不能再次选择,可以继续改进下。
