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个平民死亡 都算狼人获胜

Data类:

package com.azwcl.game;

/**
 * 游戏数据类
 * @author 吴乘龙
 * @Time 2020-9-11 22:00
 */
public class Data {
    private final String[] identity = {"平民","平民","平民","平民","预言家","女巫","猎人","白痴","狼人","狼人","狼人","狼人"};//12种身份种类
    private final Gamer[] gamers;//玩家数组
    private int prophetId;//预言家id
    private int sorceressId;//女巫id
    private int huntsmanId;//猎人id
    private int idiotId;//白痴id

    /**
     * 初始化函数,初始化gamers数组内Gamer变量
     */
    public Data(){
        this.gamers = new Gamer[12];
        for(int i = 0; i < gamers.length; i++){
            gamers[i] = new Gamer();
        }
    }

    /**
     * 获取身份方法
     * @return String[] 获取身份数组
     */
    public String[] getIdentity() {
        return identity;
    }

    /**
     * 获取游戏玩家数组
     * @return Gamer[] 游戏玩家数组
     */
    public Gamer[] getGamers() {
        return gamers;
    }

    /**
     * 获取预言家id
     * @return int 预言家id
     */
    public int getProphetId() {
        return prophetId;
    }

    /**
     * 获取女巫id
     * @return int 女巫id
     */
    public int getSorceressId() {
        return sorceressId;
    }

    /**
     * 获取猎人id
     * @return int 猎人id
     */
    public int getHuntsmanId() {
        return huntsmanId;
    }

    /**
     * 获取白痴id
     * @return int 白痴id
     */
    public int getIdiotId() {
        return idiotId;
    }

    /**
     * 设置预言家id
     * @param prophetId int 预言家id
     */
    public void setProphetId(int prophetId) {
        this.prophetId = prophetId;
    }

    /**
     * 设置女巫id
     * @param sorceressId int 女巫id
     */
    public void setSorceressId(int sorceressId) {
        this.sorceressId = sorceressId;
    }

    /**
     * 设置猎人id
     * @param huntsmanId int 猎人id
     */
    public void setHuntsmanId(int huntsmanId) {
        this.huntsmanId = huntsmanId;
    }

    /**
     * 设置白痴id
     * @param idiotId int 白痴id
     */
    public void setIdiotId(int idiotId) {
        this.idiotId = idiotId;
    }

}

Gamer类:

package com.azwcl.game;

/**
 * 游戏玩家类
 * @author 吴乘龙
 * @Time 2020-9-11 22:00
 */
public class Gamer {

    private boolean isLive;//是否活着
    private boolean isGoodPerson;//是否是好人
    private String identity;//身份

    private boolean isHavePoison;//是否有毒药
    private boolean isHaveAntidote;//是否有解药
    private boolean isReferendumDied;//免除公投死亡效果

    /**
     * 构造方法
     */
    public Gamer(){
        isLive = true;
        isHavePoison = false;
        isHaveAntidote = false;
        isReferendumDied = false;
    }



    //get和set方法

    public boolean getIsLive() {
        return isLive;
    }

    public boolean getIsGoodPerson() {
        return isGoodPerson;
    }

    public String getIdentity() {
        return identity;
    }

    public boolean getIsHavePoison() {
        return isHavePoison;
    }

    public boolean getIsHaveAntidote() {
        return isHaveAntidote;
    }

    public boolean getIsReferendumDied(){
        return isReferendumDied;
    }


    public void setIsLive(boolean live) {
        isLive = live;
    }

    public void setIsGoodPerson(boolean goodPerson) {
        isGoodPerson = goodPerson;
    }

    public void setIdentity(String identity) {
        this.identity = identity;
    }

    public void setIsHavePoison(boolean havePoison) {
        isHavePoison = havePoison;
    }

    public void setIsHaveAntidote(boolean haveAntidote) {
        isHaveAntidote = haveAntidote;
    }

    public void setIsReferendumDied(boolean referendumDied){
        isReferendumDied = referendumDied;
    }
}

Input类

package com.azwcl.game;

import java.util.InputMismatchException;
import java.util.Scanner;

/**
 * 输入类
 * @author 吴乘龙
 * @Time 2020-9-11 22:00
 */
public class Input {

    /**
     * 输入类静态方法,方便输入
     * @param expertStart int 期望输入整数的开始
     * @param expertEnd int 期望输入整数的结束
     * @param message String 输入的提示笑死
     * @param errorMessage String 输入错误的时候的提示消息
     * @return int 返回输入的整数
     */
    public static int inputOption(int expertStart, int expertEnd, String message, String errorMessage){
        System.out.println("-----+++++-----+++++-----+++++-----");
        System.out.print(message);
        int option = 0;
        while (true){
            try{
                Scanner sc = new Scanner(System.in);
                option = sc.nextByte();
                if(option > expertEnd || option < expertStart) {
                    throw new InputMismatchException();
                }
                else break;
            }catch (InputMismatchException e){
                System.out.println(errorMessage);
                System.out.print("请重新输入:");
            }
        }

        return option;
    }
}

Menu类

package com.azwcl.game;

/**
 * 游戏菜单类
 * @author 吴乘龙
 * @Time 2020-9-11 22:00
 */
public class Menu {
    /**
     * 游戏欢迎界面菜单
     * @param data Data[] 游戏数据数组
     * @param stage Stage 游戏阶段类变量
     */
    public void welcome(Data data,Stage stage){
        System.out.print("正在进入游戏中");
        Print.printDot(3);

        System.out.println("欢迎您进入狼人杀游戏,祝你游戏愉快...");
        System.out.println("-----+++++-----+++++-----+++++-----");
        System.out.println("1.开始游戏");
        System.out.println("2.退出游戏");
        int option = Input.inputOption(1,2,"请输入您的选择:", "对不起,您的选择有误!");
        if(option == 1){
            startGame(data,stage);
        }else if(option == 2) {
            gameOverMessage();
        }
    }

    /**
     * 游戏开始界面菜单
     * @param data Data[] 游戏数据数组
     * @param stage Stage 游戏阶段类变量
     */
    public void startGame(Data data,Stage stage){
        System.out.println("游戏开始了!!!");
        System.out.println("请大家准备好~~~~!!!");

        System.out.print("分配角色中");
        stage.distributionIdentity(data);
        Print.printDot(3);
        System.out.println("分配角色完毕...");
        Print.printIdentity(data);
        stage.gaming(data);
    }

    /**
     * 在欢迎界面直接退出提示
     */
    private void gameOverMessage() {
        System.out.println("不玩玩就走了吗~~~,好的吧~拜拜~");
        System.out.println("正在退出");
        Print.printDot(3);
    }
}

Print类

package com.azwcl.game;

/**
 * 简化输出方法
 * @author 吴乘龙
 * @Time 2020-9-12 13:00
 */
public class Print {
    /**
     * 输出点方法
     * @param number int 要输出的点数目
     */
    public static void printDot(int number){
        for(int i = 0 ; i < number; i++){
            try{
                Thread.sleep(300);
            }catch (InterruptedException e){
                System.out.println("游戏异常,正在退出...");
                System.exit(0);
            }
            System.out.print(".");
        }
        System.out.println();
    }

    /**
     * 打印各玩家身份
     * @param data Data[] 游戏数据
     */
    public static void printIdentity(Data data){
        System.out.println("各玩家身份:");
        for(int i = 0 ; i < 12; i++){
            System.out.print((i + 1) + " : " + data.getGamers()[i].getIdentity() + "\t");
        }
        System.out.println();
    }
}

Stage类

package com.azwcl.game;

import java.util.Arrays;
import java.util.Vector;

/**
 * 游戏阶段类
 * @author 吴乘龙
 * @Time 2020-9-11 22:00
 */
public class Stage {

    /**
     * 分配身份方法
     * @param data Data[] 游戏数据数组
     */
    public void distributionIdentity(Data data){
        Vector<String> copyIdentity = new Vector<String>(Arrays.asList(data.getIdentity()));
        for(int i = 0 ; i < 12; i++){
            int randomNum = (int) (Math.random() * (12-i));
            data.getGamers()[i].setIdentity(copyIdentity.get(randomNum));
            copyIdentity.remove(randomNum);
        }

        //分配完身份,设置data身份数据
        for(int i = 0 ; i < 12; i++){
            if(data.getGamers()[i].getIdentity().equals("平民")) {
                data.getGamers()[i].setIsGoodPerson(true);
            }
            else if(data.getGamers()[i].getIdentity().equals("狼人")) {
                data.getGamers()[i].setIsGoodPerson(false);
            }
            else if(data.getGamers()[i].getIdentity().equals("预言家")) {
                data.setProphetId(i);
                data.getGamers()[i].setIsGoodPerson(true);
            }
            else if(data.getGamers()[i].getIdentity().equals("女巫")) {
                data.setSorceressId(i);
                data.getGamers()[i].setIsHavePoison(true);
                data.getGamers()[i].setIsHaveAntidote(true);
                data.getGamers()[i].setIsGoodPerson(true);
            }
            else if(data.getGamers()[i].getIdentity().equals("猎人")) {
                data.setHuntsmanId(i);
                data.getGamers()[i].setIsGoodPerson(true);
            }
            else if(data.getGamers()[i].getIdentity().equals("白痴")) {
                data.setIdiotId(i);
                data.getGamers()[i].setIsReferendumDied(true);
                data.getGamers()[i].setIsGoodPerson(true);
            }
        }
    }

    /**
     * 晚上过程
     * @param data Data[] 游戏数据数组
     * @return 0-未结束,1-好人胜利,2-狼人胜利
     */
    public int runNight(Data data){
        System.out.println("天黑请闭眼...");

        //狼人回合
        System.out.println("狼人请睁眼...");
        int diedGamerId;
        while(true){
            diedGamerId = Input.inputOption(1,12,"狼人,请你们选择你们即将猎杀的玩家:", "输入有误,请重新输入:");
            diedGamerId -= 1;
            //判断玩家是否存活
            if(data.getGamers()[diedGamerId].getIsLive()) {
                data.getGamers()[diedGamerId].setIsLive(false);
                break;
            }
            else System.out.println("你们选择猎杀的玩家在前面的回合中已经死亡,请重新选择!");
        }

        //判断是否结束
        int res = isGamerOver(data);
        if(res != 0){
            return res;
        }

        //预言家回合
        int seeGamerIdentityId;
        if(data.getGamers()[data.getProphetId()].getIsLive() || diedGamerId == data.getProphetId()){
            System.out.println("预言家请睁眼...");

            while(true){
                seeGamerIdentityId = Input.inputOption(1,12,"预言家,请查看您想查看的身份:","输入有误,请重新输入:");
                seeGamerIdentityId -= 1;
                if(!data.getGamers()[seeGamerIdentityId].getIsLive() && diedGamerId != seeGamerIdentityId){
                    System.out.println("查看无效,您选择的人在以前的回合已死,无法查看!");
                }else break;
            }

            String seeGamerIdentity = data.getGamers()[seeGamerIdentityId].getIsGoodPerson() ? "好人" : "狼人";

            System.out.println("预言家,您查看的人是:" + seeGamerIdentity + "!");
            System.out.println("预言家请闭眼!");
        }


        //女巫行动
        System.out.println("女巫请睁眼:");
        //女巫有解药
        boolean isSave = false;
        if(data.getGamers()[data.getSorceressId()].getIsHaveAntidote()){
            System.out.println("女巫,昨晚被杀死的人是:" + (diedGamerId + 1));
            int save = Input.inputOption(0,1,"请问您是否要救(0-不救,1-救):","输入有误,请重新输入:");
            if(save == 1){
                data.getGamers()[diedGamerId].setIsLive(true);
                data.getGamers()[data.getSorceressId()].setIsHaveAntidote(false);
                isSave = true;
            }
        }
        //女巫有毒药
        int poisonId = -1;
        if(data.getGamers()[data.getSorceressId()].getIsHavePoison() && !isSave){
            int isPoison = Input.inputOption(0,1,"请问您是否要使用毒药(0-不使用,1-使用):","输入有误,请重新输入:");
            if(isPoison == 1){
                while(true){
                    poisonId = Input.inputOption(1,12, "请选择您要毒死的玩家:", "输入有误,请重新输入:");
                    poisonId -= 1;
                    if(!data.getGamers()[poisonId].getIsLive()){
                        System.out.println("您选择的人已经死了,请重新选择:");
                    }else {
                        data.getGamers()[data.getSorceressId()].setIsHavePoison(false);
                        break;
                    }
                }
            }
            data.getGamers()[poisonId].setIsLive(false);
            //判断是否结束
            res = isGamerOver(data);
            if(res != 0){
                return res;
            }
        }

        //宣布死讯
        System.out.println("白天,大家请睁眼!");
        if(isSave){
            System.out.println("昨晚是个平安夜~");
        }else if(poisonId != -1){
            System.out.println("昨晚死亡的人是:" + (diedGamerId + 1) + "号和" + (poisonId + 1) + "号玩家!");
        }else{
            System.out.println("昨晚死亡的人是" + (diedGamerId + 1) + "号玩家!");
        }


        //如果死亡的是猎人
        int huntId = -1;
        if(!isSave && (poisonId == data.getHuntsmanId() || diedGamerId == data.getHuntsmanId())){
            int isUseSkill = Input.inputOption(0,1,"猎人,昨晚您死亡了,请问,您是否发动技能开枪带走一名玩家(0-否,1-是):","输入有误,请重新输入:");
            if(isUseSkill == 1){
                while(true){
                    huntId = Input.inputOption(1,12, "请选择您要猎杀的玩家:", "输入有误,请重新输入:");
                    huntId -= 1;
                    if(!data.getGamers()[huntId].getIsLive()){
                        System.out.println("您选择的人已经死了,请重新选择:");
                    }else break;
                }
            }
            data.getGamers()[huntId].setIsLive(false);
            //判断是否结束
            res = isGamerOver(data);
            if(res != 0){
                return res;
            }
        }
        return 0;
    }

    /**
     * 白天过程
     * @param data Data[] 游戏数据数组
     * @return 0-未结束,1-好人胜利,2-狼人胜利
     */
    public int runDaytime(Data data){
        //活着的人存入
        Vector<Integer> liveGamers = new Vector<Integer>();
        for(int i = 0 ; i < 12; i++){
            if(data.getGamers()[i].getIsLive()){
                liveGamers.add(i);
            }
        }
        //随机指定人发言
        for(int i = liveGamers.size(); i > 0; i--){
            int talkGamerId = (int) (Math.random() * i);
            System.out.println("请" + (liveGamers.get(talkGamerId)+ 1) + "号玩家发言:");
            liveGamers.remove(talkGamerId);
        }


        //投票
        int diedOutId = -1;
        while(true){
            diedOutId = Input.inputOption(1,12,"请大家商讨,决定要票出的玩家:","输入有误,请重新输入:");
            diedOutId -= 1;
            if(!data.getGamers()[diedOutId].getIsLive()){
                System.out.println("该玩家以前的回合已经死了,请重新决定!");
                continue;
            }
            break;
        }

        System.out.println("你们票出的玩家是:" + (diedOutId + 1));

        data.getGamers()[diedOutId].setIsLive(false);
        //判断是否结束
        int res = isGamerOver(data);
        if(res != 0){
            return res;
        }

        //票出的玩家是猎人:
        int huntId = -1;
        if(data.getGamers()[diedOutId].getIdentity().equals("猎人")) {
            int isUseSkill = Input.inputOption(0, 1, "猎人,您被各位玩家票出,请问,您是否发动技能开枪带走一名玩家(0-否,1-是):", "输入有误,请重新输入:");
            if (isUseSkill == 1) {
                while (true) {
                    huntId = Input.inputOption(1, 12, "请选择您要猎杀的玩家:", "输入有误,请重新输入:");
                    huntId -= 1;
                    if (!data.getGamers()[huntId].getIsLive()) {
                        System.out.println("您选择的人已经死了,请重新选择:");
                    } else break;
                }
            }
            data.getGamers()[huntId].setIsLive(false);
            //判断是否结束
            res = isGamerOver(data);
            if(res != 0){
                return res;
            }
        }

        //票出的玩家是白痴:
        if(data.getGamers()[diedOutId].getIdentity().equals("白痴")){
            if(data.getGamers()[data.getIdiotId()].getIsReferendumDied()){
                int isUseSkill = Input.inputOption(0, 1, "白痴,您被各位玩家票出,请问,您是否发动技能保证自己活下来(0-否,1-是):", "输入有误,请重新输入:");
                if(isUseSkill == 1){
                    System.out.println("白痴发动技能生效,免除公投一次");
                }else
                    data.getGamers()[diedOutId].setIsLive(false);
            }
        }
        //判断是否结束
        res = isGamerOver(data);
        if(res != 0){
            return res;
        }
        else return 0;
    }

    /**
     * 判断游戏是否结束
     * @param data Data[] 游戏数据数组
     * @return int 0-未结束,1-好人胜利,2-狼人胜利
     */
    public int isGamerOver(Data data){
        //判断游戏是否结束了
        int personNum = 0, wolfNum = 0, godNum = 0;
        for(int i = 0 ; i < 12; i++){
            if(data.getGamers()[i].getIsLive()){
                if(data.getGamers()[i].getIdentity().equals("狼人")) wolfNum++;
                else if(data.getGamers()[i].getIdentity().equals("平民")) personNum++;
                else godNum++;
            }
        }

        if(wolfNum == 0) return 1;
        else if(personNum == 0) return 2;
        else if(godNum == 0) return 2;
        else return 0;
    }

    /**
     * 游戏阶段
     * @param data Data[] 游戏数据数组
     */
    public void gaming(Data data){
        int res;
        while (true){
           res = runNight(data);
           if(res != 0) break;
            res = runDaytime(data);
            if(res != 0) break;
        }
        theGameOver(res);
    }

    /**
     * 游戏结束阶段
     * @param res int 最后胜利结果
     */
    public void theGameOver(int res){
        if(res == 1){
            System.out.println("游戏结束,好人胜利");
        }else if(res == 2){
            System.out.println("游戏结束,狼人胜利");
        }
        System.out.println("欢饮下次继续玩耍~~~");
        System.out.println("正在退出");
        Print.printDot(3);
    }
}

Main类

package com.azwcl.game;


/**
 * 主类
 * @author 吴乘龙
 * @Time 2020-9-12 14:00
 */
public class Main {
    /**
     * 主类启动
     * @param args String[] 启动方法参数
     */
    public static void main(String[] args) {
        Data data =  new Data();
        Stage stage = new Stage();

        Menu menu = new Menu();

        menu.welcome(data,stage);
    }
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值