概述
胜利条件:
- 所有单位安全渡河
游戏模式:
- 经典模式(农夫,狼,羊,菜),狼会吃羊、羊会吃菜,小船最大承载量为
2
- 全新模式(农夫,狼,羊,菜,兔子,胡萝卜),狼会吃羊、羊会吃菜、兔子会吃胡萝卜,小船最大承载量为
3
- 地狱模式(农夫,狼,羊,菜,兔子,胡萝卜),狼会吃羊、狼会吃兔子、羊会吃菜、兔子会吃白菜、兔子会吃胡萝卜,小船最大承载量为
3
用到的知识
- 继承,封装,多态
待完善
- 逻辑不通的地方(在农夫不在某对象旁边时,仍然可带其过河)
- 优化创建实体时的个性的播报(多了两个只用来个性播报的空壳类
Wolf,Sheep
)(解决方法:在构造函数加一个创建时要说的话)- 输出失败原因
- 增加船的使用次数和状态显示
- 直接给
isAlive
和crossRiver
赋初值而不必使用构造器- 优化携带对象过河的交互,允许乱序输入过河对象
- 更多游戏角色
- 地狱模式
- 优化
ArrayList
crosses
- 优化职责
- 在菜单输出之后输出 ”不在同一侧“ 的提醒
- 优化菜单(只显示农夫侧的对象(states也不必show了))(逆向优化?)
- 添加挑战模式(用最少的操作次数完成渡河才可以赢)
- 优化GameGui
- 使用抽象/接口
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
GameGui.welcome();
switch (in.nextInt()) {
case 1: {
Game game = new Game();
game.play();
break;
}
case 2: {
Game2 game2 = new Game2();
game2.play();
break;
}
case 3: {
Game3 game3 = new Game3();
game3.play();
break;
}
}
}
}
class Game {
Objs wolf, sheep, cabbage, farmer;
Transporter boat;
Objs[] crosser;
Game() {
boat = new Transporter("我是送大家去对岸的", "Boat", 2, 11);
wolf = new Objs("啊呜~~~我", "Wolf", "狼又回来了");
sheep = new Objs("咩咩,我是可爱的小羊", "Sheep");
cabbage = new Objs("NONE", "Cabbage");
farmer = new Objs("NONE", "Farmer");
}
protected void play() {
crosser = getCrosses();
while (true) {
GameGui.menu(crosser);
boolean[] choices = getChoices();
if (cantCross(choices)) continue;
boat.crossRiver(choices, crosser);
AnimalsToEat();
showStatus();
if (isGameOver()) break;
}
over(crosser);
}
public Objs[] getCrosses() {
return new Objs[]{null, farmer, wolf, sheep, cabbage};
}
private boolean[] getChoices() {
Scanner input = new Scanner(System.in);
boolean[] choices = new boolean[10];
boolean Wrong;
do {
Wrong = false;
try {
while (input.hasNext()) {
String s = input.next();
if (s.equals("0")) System.exit(0);
if (s.equals("#")) break;
int id = Integer.parseInt(s);
choices[id] = true;
}
} catch (Exception e) {
System.out.println("输入有误,请重新输入!");
Wrong = true;
}
} while (Wrong);
return choices;
}
// 判断是否有农夫,判断是否超载
public boolean cantCross(boolean[] choices) {
if (!choices[1] || outOfObjs(choices)) {
System.out.println("!!!您的输入不可实现!!!");
return true;
}
if (boat.overMaxLoad(choices)) {
System.out.println("超载啦!走不成哦!");
return true;
}
return false;
}
// 判断是否有超出对象编号的选项
private boolean outOfObjs(boolean[] choices) {
for (int i = crosser.length; i < choices.length; i++) {
if (choices[i]) return true;
}
return false;
}
// 让动物们可以去吃
public void AnimalsToEat() {
wolf.eat(farmer, sheep);//狼吃羊,如果羊不在同一边,则吃不到,如果在同一边,羊被吃
sheep.eat(farmer, cabbage);//同上
}
/*
* 判断游戏是否结束
* 运算:羊、白菜任一个实体被吃,游戏结束,或者狼、羊、白菜均未被吃且全部渡过河,游戏结束
* 输出:游戏结束--返回true ,未结束--返回false
*/
public boolean isGameOver() {
for (Objs o : crosser) if (o != null && o.isDead()) return true;
for (Objs o : crosser) if (o != null && !o.getHasCross()) return false;
return true;
}
/*
* 判断游戏是否胜利
* 前置条件:游戏结束
* 运算:狼、羊、白菜均未被吃且全部渡过河,游戏胜利,否则失败
* 输出:游戏胜利--返回true ,失败--返回false
*/
public boolean hasWin(Objs[] objs) {
for (Objs o : objs) if (o != null && o.isDead()) return false;
for (Objs o : objs) if (o != null && !o.getHasCross()) return false;
return true;
}
// 显示状态
private void showStatus() {
/* 输出农夫、各种动物、物品的状态(生存、位置) */
System.out.println("====================== States =======================");
for (Objs t : crosser) if (t != null) t.showStatus();
boat.showStatus();
}
// 结束游戏
protected void over(Objs[] objs) {
if (hasWin(objs)) {
System.out.println("\n*****************************************************");
System.out.println("*************** game over: you win ! ****************");
} else {
System.out.println();
howLose(boat, objs);
System.out.println("*****************************************************");
System.out.println("*************** game over: you lose ! ***************");
}
System.out.println("*****************************************************");
System.exit(0);
}
// 输出失败原因
protected void howLose(Transporter boat, Objs[] objs) {
if (boat.isDead()) System.out.println("");
for (Objs obj : objs)
if (obj != null && obj.isDead()) System.out.println("");
}
}
class Game2 extends Game {
Objs rabbit, carrot;
public Game2() {
rabbit = new Objs("我是最机灵的兔子", "Rabbit");
carrot = new Objs("NONE", "Carrot");
boat.setTakingNum(3);
boat.setUseTime(13);
}
@Override
public Objs[] getCrosses() {
return new Objs[]{null, farmer, wolf, sheep, rabbit, cabbage, carrot};
}
@Override
public void AnimalsToEat() {
wolf.eat(farmer, sheep); //若wolf与sheep在同一侧且农夫不在,wolf会吃掉sheep
wolf.eat(farmer, rabbit);
sheep.eat(farmer, cabbage);
rabbit.eat(farmer, carrot);
}
}
class Game3 extends Game2 {
@Override
public void AnimalsToEat() {
wolf.eat(farmer, sheep); //若wolf与sheep在同一侧且农夫不在,wolf会吃掉sheep
wolf.eat(farmer, rabbit);
sheep.eat(farmer, cabbage);
sheep.eat(farmer, carrot);
rabbit.eat(farmer, carrot);
rabbit.eat(farmer, cabbage);
}
}
class GameGui {
public static void welcome() {
System.out.println("选择要进行的游戏模式:\n" +
"1:经典模式(农夫,狼,羊,菜):(农夫不在身边时)狼吃羊、羊吃菜\n" +
"2:全新模式(农夫,狼,羊,菜,兔子,萝卜):(农夫不在身边时)狼吃羊、狼吃兔、羊吃菜、兔子吃萝卜\n" +
"3:地狱模式(农夫,狼,羊,菜,兔子,萝卜):(农夫不在身边时)狼吃羊、狼吃兔、羊吃菜、羊吃萝卜、兔子吃萝卜、兔子吃菜");
}
public static void menu(Objs[] crosser) {
/* 显示菜单 */
System.out.println("============== Please choose operation ==============");
System.out.println("请将要渡河的对象的序号以空格间隔输入,并以 # 结尾来确认您的输入");
System.out.println("0:退出游戏");
for (int i = 1; i < crosser.length - 1; i += 2) {
System.out.println(i + ":" + crosser[i].getName() + " \t" + (i + 1) + ":" + crosser[i + 1].getName());
}
}
}
class Objs {
private final String name;
private boolean isAlive = true; //初始化 活
private boolean hasCross = false;
public Objs(String Saying, String name) {
this.name = name;
if (!Saying.equals("NONE")) System.out.println(Saying + " " + " " + name);
}
// 为狼重载出场播报
public Objs(String Saying1, String name, String Saying2) {
this.name = name;
if (!Saying1.equals("NONE")) System.out.println(Saying1 + " " + name + " " + Saying2);
}
/* 输出农夫、各种动物、物品的状态(生存、位置) */
public void showStatus() {
System.out.printf("\t\t%-8s \t%11s CrossedRiver\n", name, hasCross ? "is" : "isNot");
}
public void eat(Objs farmer, Objs objs2) {
if (hasCross == objs2.getHasCross()) {//调用者和传入者在一起
if (hasCross != farmer.getHasCross()) {//是否和农夫在一起
killObj(objs2);
}
}
}
private static void killObj(Objs objs) {
objs.isAlive = false;
}
/* Getter And Setter*/
public String getName() {
return name;
}
public boolean isDead() {
return !isAlive;
}
public boolean getHasCross() {
return hasCross;
}
public void cross() {
this.hasCross = !this.hasCross;
}
}
class Transporter extends Objs {
private int takingNum; //核载
private int useTime; //使用次数
public Transporter(String saying, String name, int takingNum, int useTime) {
super(saying, name);
this.takingNum = takingNum;
this.useTime = useTime;
}
/*
* 将所有对象运输到对岸
* 使用次数减1
*/
public void crossRiver(boolean[] choices, Objs[] objs) {
for (int i = 2; i < objs.length; i++) {
if (!choices[i]) continue;
if (!onSameSide(objs[1], objs[i])) return; //若某对象不在农夫旁边,则渡河失败
}
for (int i = 0; i < choices.length; i++) if (choices[i]) objs[i].cross(); //使选择的对象过河
useTime--;
}
// 是否超载
protected boolean overMaxLoad(boolean[] choices) {
int cnt = 0;
for (boolean b : choices) if (b) cnt++;
return cnt > takingNum;
}
@Override
public void showStatus() {
if (useTime > 7) System.out.println("\t\t" + getName() + " will be destroyed after " + useTime + " uses");
else
System.out.println("!!!!!!!! " + getName() + " will be destroyed after " + useTime + " uses" + " !!!!!!!!");
}
private static boolean onSameSide(Objs objs1, Objs objs2) {
if (objs1.getHasCross() == objs2.getHasCross()) return true;
else {
System.out.println("!!!!" + objs1.getName() + " and " + objs2.getName() + " are not on the same side!!!!");
return false;
}
}
/* Getter And Setter */
@Override
public boolean isDead() {
return useTime <= 0;
}
public void setTakingNum(int takingNum) {
this.takingNum = takingNum;
}
public void setUseTime(int useTime) {
this.useTime = useTime;
}
}
不会有人赢不了吧若本贴对您有帮助,欢迎点赞收藏!
由于作者时间、能力有限,代码中难免有不足之处,还望读者海涵并不吝赐教。