Unity3d: 牧师与魔鬼动作分离版

说明:基于牧师与魔鬼进行改进

1 作业要求

牧师与魔鬼 动作分离版

设计一个裁判类,当游戏达到结束条件时,通知场景控制器游戏结束

2 实现细节

在原来代码的基础上,修改如下:

  • 将UserGUI的sign成员变量和Controller的Check方法提取到了Judge中,并在Controller中添加了获得游戏状态的方法和判断游戏状态的方法
  • 把UserGUI的IsShowRules成员变量放到了Judge中,并在Controller中添加了设置和获取方法、
  • 把BoatModel的IsEmpty提取到了Judge中
  • 把RoleModel的IsOnBoat放到了Judge中

经过修改后:

用户界面UserGUI就可以通过调用Controller提供用户接口action去询问来自裁判类的判断。

Controller新增加的接口如下:


        private Judge judge;
        
        public void setGameState(int state) {
            judge.setGameState(state);
        }

        public int getGameState() {
            return judge.getGameState();
        }

        public bool isPlaying() {
            return judge.getGameState() == 0;
        }

        public bool isLose() {
            return judge.getGameState() == 1;
        }

        public bool isWin() {
            return judge.getGameState() == 2;
        }

        public bool isPause() {
            return judge.getGameState() == 3;
        }

Judge实现如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Mygame {

    public class Judge {
        private int gamestate = 0; //=0表示游戏在进行,=1表示游戏失败,=2表示游戏胜利,=3表示游戏停止
        private bool isShowRules = false;

        public void setGameState(int state) {
            gamestate = state;
        }

        public int getGameState() {
            return gamestate;
        }

        public bool isPlaying() {
            return gamestate == 0;
        }

        public void setIsShowRules(bool flags) {
            isShowRules = flags;
        }

        public bool getIsShowRules() {
            return isShowRules;
        }

        /*判断船是否是空的,空船不能移动*/
        public bool IsEmptyBoat(BoatModel boat) {
            RoleModel[] roles = boat.getRoles();
            for (int i = 0; i < roles.Length; ++i){
                if (roles[i] != null)
                    return false;
            }
            return true;
        }

        public bool IsOnBoat(RoleModel role) {
            return role.getIsOnBoat();
        }

        /*检查游戏是否结束*/
        public int Check(LandModel start_land, LandModel destination, BoatModel boat){
            int start_priest = (start_land.GetRoleNum())[0];
            int start_devil = (start_land.GetRoleNum())[1];
            int end_priest = (destination.GetRoleNum())[0];
            int end_devil = (destination.GetRoleNum())[1];
            //终点有全部对象,游戏胜利
            if (end_priest + end_devil == 6){
                gamestate = 2;
                return 2;
            } 
                
            //统计岸的一边(包括船和陆地上)魔鬼和牧师各自的数量
            int[] boat_role_num = boat.GetRoleNumber();
            if (boat.GetBoatSign() == 1) 
            {
                start_priest += boat_role_num[0];
                start_devil += boat_role_num[1];
            }
            else
            {
                end_priest += boat_role_num[0];
                end_devil += boat_role_num[1];
            }

            //起点存在牧师且魔鬼数量大于牧师,牧师被吃,游戏失败
            if (start_priest > 0 && start_priest < start_devil)
            {      
                gamestate = 1;
                return 1;
            }
            //终点存在牧师且魔鬼数量大于牧师,牧师被吃,游戏失败
            if (end_priest > 0 && end_priest < end_devil)
            {
                gamestate = 1;
                return 1;
            }
            gamestate = 0;
            return 0;
        }
    }
}

UserGUI通过调用action.getIsShowRules(),action.isPause(),action.isLose(),action.isWin()来判断是否展现规则,是否暂停,输或者赢。

3 游戏结果截图:

开始页面:
1
游戏页面:

2

查看规则:

请添加图片描述

游戏暂停:

请添加图片描述

游戏成功:
请添加图片描述

游戏失败:

请添加图片描述

4 相关资源

代码仓库
演示视频

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用深度优先搜索算法解决渡河问题的C++代码,其中包括了输入牧师人数和小船载客人数的功能: ```c++ #include <iostream> #include <vector> using namespace std; int n; // 牧师人数(即野人人数) int c; // 小船一次至多载客人数c vector<int> left_bank; // 左岸 vector<int> right_bank; // 右岸 void dfs(int cur, vector<int>& from, vector<int>& to) { if (from.size() == 0) return; // 没人可移动,结束递归 for (int i = 0; i < from.size(); i++) { if (from[i] <= cur) { // 当前人数小于等于船载人数 int p = from[i]; from.erase(from.begin() + i); // 从from中删除该人 to.push_back(p); // 将该人移动到to if (from.size() == 0 || (to.size() > 1 && to[to.size() - 2] > to[to.size() - 1])) { // 判断是否合法 from.insert(from.begin() + i, p); // 不合法,回溯 to.pop_back(); continue; } if (to.size() == n) { // 完成目标 cout << "成功:"; for (int j = 0; j < left_bank.size(); j++) { cout << left_bank[j] << " "; } cout << " | "; for (int j = 0; j < right_bank.size(); j++) { cout << right_bank[j] << " "; } cout << endl; } else { dfs(cur - p, to, from); // 继续递归 } from.insert(from.begin() + i, p); // 回溯 to.pop_back(); } } } int main() { cout << "请输入牧师人数(即野人人数):"; cin >> n; cout << "请输入小船一次至多载客人数:"; cin >> c; for (int i = 1; i <= n; i++) { left_bank.push_back(i); } dfs(c, left_bank, right_bank); return 0; } ``` 输入示例: ``` 请输入牧师人数(即野人人数):3 请输入小船一次至多载客人数:2 ``` 输出示例: ``` 成功:3 2 1 | 成功:3 1 2 | 成功:2 3 1 | 成功:1 3 2 | 成功:2 1 3 | 成功:1 2 3 | ``` 说明:每行表示一次成功的移动,左岸和右岸分别用竖线隔开。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值