一、实验目的
- 掌握Java语言中final关键字的含义及使用方法;
- 掌握Java语言中抽象类的基本概念及使用方法;
- 掌握Java语言中接口的基本概念及使用方法;
- 理解程序设计中常用数据结构的用法;
- 掌握Java语言中List相关类的使用方法;
- 掌握Java语言中Map相关类的使用方法;
二、实验要求
1、对实验中要求的代码进行上机调试,完成实验指导书中全部实验内容。
2、编写实验报告。
三、实验步骤
1、阅读给出的部分代码和题目描述;
2、先写出各部分的注释(常见的注释有:类的功能注释;类的属性注释和方法的功能注释;类方法的入口参数和返回值注释、选择结构和循环结构注释);
先给出整体类图
MaterialObject:抽象物品类
属性:
isExist:物体生存状态;
place:物体所在地;
type:物体类型;
方法:
diedOut()物体被吃(死掉了);
showStatus()展示物体当前的状态
Animal:动物类
方法:
addedToRecipe(MaterialObject m)添加某物品进该动物的食谱
isFood(MaterialObject m)判断某物品是否在它的食谱中
canBeEat(MaterialObject m,Person farmer)判断某物品能不能被吃到
eat(MaterialObject m)吃某样食物
Person:人类
Plante:植物类
AbstracTransport:抽象交通工具类
属性:
place:所在地;
capacity:容量;
goodes:船上的货物列表;
farmer:撑船人;
方法:
moveTo(String destination)移动到目的地
Boat:船类
方法:
crossRiver()过河
board(MaterialObject m)物品m上船
disembark(MaterialObject m)物品m下船
display()展示船上的物体
AbstractGame:抽象游戏类
属性:
gameOverRule:游戏结束规则;
gameSuccessRule:游戏输赢规则;
gameData:游戏数据;
方法:
play()执行游戏
Game:游戏类
属性:
sc:输入
gameUI:游戏界面
GameData:游戏数据类
属性:游戏中的所有物体和包含这些物体的一个集合
GameUI:游戏界面类
属性:
sc:输入
方法:
menu1()第一个游戏界面
menu2()第二个游戏界面
showStatus()展示当前所有物体(除去交通工具)的状态
AbstractRule:抽象规则类
方法:
judge()根据规则判断结果
CrossRiverRule:判断是否都渡过河的规则类
ObjectExistRule:判断物品是否都还存在的规则类
GameOverRule:判断游戏是否结束的规则类
GameSuccessRule:判断游戏输赢的规则类
Cry:输出哭泣状态的接口
Happy:输出高兴状态的接口
3、书写代码,首先保证无语法错误;
4、测试代码并修正代码中的可能错误和疏漏;
1.在判断物体是否在它的食谱中的方法中,不能直接使用contains函数,因为place发生变化时,结果会出现差错。举个例子:因为添加食谱是在游戏一开始时就进行的,那么灰太狼的食谱中就会存在“喜羊羊”,“未过河”,“还活着”,如果灰太狼和喜羊羊一起过河了,并且农夫并且离开了,灰太狼准备吃掉喜羊羊,此时喜羊羊为“喜羊羊”,“已过河”,“还活着”,由于place发生改变,所以在灰太狼的食谱中是没有此时的喜羊羊的,故isFood返回false。(灰太狼:呜呜呜,都送到口边了还不能吃)
2.在判断物体能不能吃的时候,记得加农夫啊!!!(小声:实验指导书上的参数里没写农夫)
3.在将船上所有的物体装载过河时记得要将船和撑船人(农夫)也过河,这两个我是单独操作的,没有加在船上。每次过河后记得将船上的物体清空。
4.将物体装上船的board方法首先需要判断物体和船有没有在同一边,其次在判断物体是否已经在船上,不能重复添加;判断物体是否已经在船上的时候可以使用contains函数,具体原因见下图注释;在判断能否继续承载物体时,有两种方法,一是每次装载物体时比较船上的货物的数量goodses.size()和船的总容量capacity-1(农夫占了一个位置)的大小,二是每次每次装载货物后setcapaity--来更新船上的剩余容量,为0时表示船上不能继续装载物体了,这样做的话就需要用一个变量备份一下最开始的船的容量或者在过河后capacity+=goodses来更新容量,本人这里用的是第一种。
5.将物体卸下船的disembark方法和物体装上船的方法判断思路差不多,首先先判断物体有没有在船上,这里可以直接使用remove函数,返回值为boolean类型。
6.为了调用父类中没有animal中特有的方法,需要使用instanceof语句转换类型。
7.游戏初始化操作
8.一个重大bug!!!
这个bug还是我写PTA的时候调试出来的一个隐藏漏洞,就是arraylist自带的contains函数不能随便乱用,之前我一直以为这次实验中的contains函数就是遍历一下集合看两个字符串type,place比较内容看有没有相同的,isexist比较相不相同,但实际上不是这样的!当contains的输入参数是一个类时,比较时会调用equals方法,如果说类中没有重写这个方法的话那么不会发生编译错误,而是在调用该类父类(Object)中的equals()方法,而Object中的equals()方法比较的是地址!这次实验过程中存在这个bug而没有体现的原因是每个物体都有一个单独的地址空间,每次比较地址时返回的是true,故没有体现,但是为了符合游戏逻辑,本人在游戏中加上了如下的代码。
5、在规定的最后期限前提交代码。
四、实验结果
通过游戏的解法如下(思路是先把羊和兔子带过河、独自回来、带狼过去、把羊和兔子带回来、把胡萝卜和白菜带过去、独自回来、把羊和兔子带过河):
把羊和兔子装上船
过河
将狼装上船
过河
将羊和兔子装上船
将白菜和胡萝卜装上船
过河
过河
将羊和兔子装上船
过河,游戏成功
重复将物体装上船的情况:
物体和船不在同一边的情况:
将物体卸下船的情况
船上没有要卸下的物体的情况
查看船上承载的物体
装了白菜和胡萝卜后
查看各物体当前的状态
返回上一级菜单
初始化游戏重新开始玩
结束游戏
输入选项错误的情况
接口效果展示:
五、实验小结
总体来说这两次实验都不算太难,主要难点我觉得是类的设计上和一些细节问题,设计照着类图写就行了,理清楚类与类之间的联系这两次实验还是很简单的,通过这次实验我掌握了Java语言中抽象类的基本概念及使用方法和接口的基本概念及使用方法、理解了程序设计中常用数据结构的用法并且掌握Java语言中List相关类的使用方法和Map相关类的使用方法。总而言之,收获很大!写完实验报告后又发现了bug又来加一句:还理解了arraylist中的contains()函数实现,明白了这个函数的具体实现和注意问题,踩坑心得!
六、附录
package shiyan4_2;
public abstract class AbstractGame
{
private AbstractRule gameOverRule=new GameOverRule();
private AbstractRule gameSuccessRule=new GameSuccessRule();
private GameData gameData=new GameData();
public AbstractGame() {
}
public AbstractGame(AbstractRule gameOverRule, AbstractRule gameSuccessRule, GameData gameData) {
this.gameOverRule = gameOverRule;
this.gameSuccessRule = gameSuccessRule;
this.gameData = gameData;
}
public AbstractRule getGameOverRule() {
return gameOverRule;
}
public void setGameOverRule(AbstractRule gameOverRule) {
this.gameOverRule = gameOverRule;
}
public AbstractRule getGameSuccessRule() {
return gameSuccessRule;
}
public void setGameSuccessRule(AbstractRule gameSuccessRule) {
this.gameSuccessRule = gameSuccessRule;
}
public GameData getGameData() {
return gameData;
}
public void setGameData(GameData gameData) {
this.gameData = gameData;
}
abstract public int play();
}
package shiyan4_2;
import java.util.ArrayList;
public abstract class AbstractRule
{
public abstract boolean judge(ArrayList<MaterialObject> objects);
}
package shiyan4_2;
import java.util.ArrayList;
public abstract class AbstractTransport
{
private String place; //所在地
private int capacity; //容量
private ArrayList<MaterialObject> goodses = new ArrayList<>(); //货物列表
private Person farmer;
public AbstractTransport() {
}
public AbstractTransport(String place, int capacity, Person farmer)
{
this.place = place;
this.capacity = capacity;
this.farmer = farmer;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public ArrayList<MaterialObject> getGoodses() {
return goodses;
}
public void setGoodses(ArrayList<MaterialObject> goodses) {
this.goodses = goodses;
}
public Person getFarmer() {
return farmer;
}
public void setFarmer(Person farmer) {
this.farmer = farmer;
}
public void moveTo(String place) //将该交通工具移往某处
{
setPlace(place);
}
}
package shiyan4_2;
import java.util.HashSet;
public class Animal extends MaterialObject
{
private HashSet<MaterialObject> recipe=new HashSet<>();
public Animal()
{
}
public Animal(String type, String place, boolean isExist) {
super(type, place, isExist);
}
public HashSet<MaterialObject> getRecipe() {
return recipe;
}
public void setRecipe(HashSet<MaterialObject> recipe) {
this.recipe = recipe;
}
//吃掉该物体
public void eat(MaterialObject object)
{
System.out.println(this.getType()+"说");
this.happy();
object.diedOut();
System.out.println(object.getType()+"说");
object.cry();
}
//添加一个物体到食谱中去
public void addedToRecipe(MaterialObject object)
{
this.recipe.add(object);
}
//判断物体是否在它的食谱中
public boolean isFood(MaterialObject object)
{
//注意这里不能直接使用contains函数,因为当place发生变化时,结果会出现差错
for(MaterialObject food : recipe)
{
if (food.getType().equals(object.getType())) return true;
}
return false;
}
//判断某物体能不能被吃到
public boolean canBeEat(MaterialObject object, Person farmer)
{
if(object.getPlace().equals(this.getPlace())&&isFood(object)&&!object.getPlace().equals(farmer.getPlace()))
{
return true;
}
else
{
return false;
}
}
}
package shiyan4_2;
public class Boat extends AbstractTransport
{
public Boat() {
}
public Boat(String place, int capacity, Person farmer)
{
super(place, capacity, farmer);
}
//将船上的所有物体装载过河(船也过河了)
public void crossRiver()
{
for(MaterialObject object:getGoodses())
{
if(object.getPlace().equals("未过河")) object.setPlace("已过河");
else object.setPlace("未过河");
}
if(this.getPlace().equals("未过河")) this.setPlace("已过河");
else this.setPlace("未过河");
if(getFarmer().getPlace().equals("未过河")) getFarmer().setPlace("已过河");
else getFarmer().setPlace("未过河");
getGoodses().clear(); //将船上的所有物体清空
}
//将物体装载上船
public void board(MaterialObject object)
{
//首先先判断该物体和船有没有在同一边,其次再判断物体是否已经在船上
if(this.getPlace().equals(object.getPlace()))
{
/*此时可以直接用自带的contains函数,因为经历过上一回合后,游戏没有结束
说明没有物体死亡(isexist不会变)并且上一次清空了船上的所有物体,在河的一侧
不会存在因为place不同而出现将两个对象都装上船的情况*/
if(getGoodses().contains(object))
{
System.out.println(object.getType()+"已经待在船上了!");
return ;
}
//如果该物体没有在船上,判断容量是否还足够
if(getGoodses().size()<getCapacity()-1)
{
System.out.println("已经将"+object.getType()+"装上船");
getGoodses().add(object);
System.out.println("船的剩余容量为"+(getCapacity()-1-getGoodses().size()));
}
else
{
System.out.println("船上的容量不够了,装不下啦!");
}
}
else
{
System.out.println(object.getType()+"和船不在同一边,装不了啊!");
}
}
//将物体卸下船
public void disembark(MaterialObject object)
{
//首先判断该物体有没有在船上,remove函数返回的是boolean类型
if(getGoodses().remove(object))
{
System.out.println("已经将"+object.getType()+"卸下船");
System.out.println("船的剩余容量为"+(getCapacity()-1-getGoodses().size()));
}
else
{
System.out.println("船上没有"+object.getType()+"啊!");
}
}
public void display() //展示在船上的物体
{
System.out.println("在船上的物体有");
System.out.print("勤劳的农夫");
for(MaterialObject object:getGoodses())
{
System.out.print(" "+object.getType());
}
}
}
package shiyan4_2;
import java.util.ArrayList;
public class CrossRiverRule extends AbstractRule
{
//判断所有物品是否都渡过了河
@Override
public boolean judge(ArrayList<MaterialObject> objects)
{
for(MaterialObject object:objects)
{
if(object.getPlace().equals("未过河"))
{
return false;
}
}
return true;
}
}
package shiyan4_2;
public interface Cry
{
public void cry();
}
package shiyan4_2;
import java.util.Scanner;
public class Game extends AbstractGame
{
Scanner sc = new Scanner(System.in);
private GameUI gameUI = new GameUI();
@Override
public int play()
{
boolean gameover=false;
boolean win=false;
int choice1=-1;
int choice2=-1;
while(!gameover) //判断游戏有没有结束
{
choice1=gameUI.menu1();
if(choice1==0) return -1;
else if(choice1==1)
{
choice2=gameUI.menu2();
switch(choice2)
{
case 0:
return -1;
case 1:
getGameData().getBoat().board(getGameData().getWolf());
break;
case 2:
getGameData().getBoat().board(getGameData().getSheep());
break;
case 3:
getGameData().getBoat().board(getGameData().getRabbit());
break;
case 4:
getGameData().getBoat().board(getGameData().getCabbage());
break;
case 5:
getGameData().getBoat().board(getGameData().getCarrot());
break;
case 6:
break;
}
}
else if(choice1==2)
{
choice2=gameUI.menu2();
switch(choice2)
{
case 0:
return -1;
case 1:
getGameData().getBoat().disembark(getGameData().getWolf());
break;
case 2:
getGameData().getBoat().disembark(getGameData().getSheep());
break;
case 3:
getGameData().getBoat().disembark(getGameData().getRabbit());
break;
case 4:
getGameData().getBoat().disembark(getGameData().getCabbage());
break;
case 5:
getGameData().getBoat().disembark(getGameData().getCarrot());
break;
case 6:
break;
}
}
else if(choice1==3)
{
getGameData().getBoat().display();
}
else if(choice1==4)
{
gameUI.showStatus(getGameData().getObjects());
}
else if(choice1==5)
{
getGameData().getBoat().crossRiver();
}
else if(choice1==6)
{
return 0;
}
if (gameover)
{
System.out.println("游戏已终止");
return -1;
}
//为了调用animal中特有的吃物体相关操作,使用instanceof语句
for(MaterialObject object1:getGameData().getObjects())
{
for(MaterialObject object2:getGameData().getObjects())
{
if(object1 instanceof Animal animal1) //如果object1是动物,则转换为动物类型
{
if(animal1.canBeEat(object2, getGameData().getFarmer()))
{
animal1.eat(object2);
}
}
}
}
System.out.println();
System.out.println("------------------------------------");
//gameUI.showStatus(getGameData().getObjects());
gameover = getGameOverRule().judge(getGameData().objects);
}
win = getGameSuccessRule().judge(getGameData().objects);
if (win)
{
gameUI.showStatus(getGameData().getObjects());
System.out.println("农夫说");
getGameData().getFarmer().happy();
System.out.println("太棒了,你成功通过了游戏!");
}
else
{
gameUI.showStatus(getGameData().getObjects());
System.out.println("游戏失败了0.0,小可爱,要不再试一次吧!");
}
sc.close();
return -1;
}
}package shiyan4_2;
import java.util.ArrayList;
public class GameData
{
private Person farmer;
private Animal wolf;
private Animal sheep;
private Animal rabbit;
private Plant cabbage;
private Plant carrot;
private Boat boat;
ArrayList<MaterialObject> objects=new ArrayList<>();
public GameData()
{
farmer=new Person("勤劳的农夫","未过河",true);
wolf=new Animal("灰太狼","未过河",true);
sheep=new Animal("喜羊羊","未过河",true);
rabbit=new Animal("大白兔","未过河",true);
cabbage=new Plant("大白菜","未过河",true);
carrot=new Plant("胡萝卜","未过河",true);
boat=new Boat("未过河",3,farmer);
objects.add(farmer);
objects.add(wolf);
objects.add(sheep);
objects.add(cabbage);
objects.add(carrot);
objects.add(rabbit);
wolf.addedToRecipe(getSheep());
wolf.addedToRecipe(getRabbit());
sheep.addedToRecipe(getCabbage());
sheep.addedToRecipe(getCarrot());
rabbit.addedToRecipe(getCabbage());
rabbit.addedToRecipe(getCarrot());
}
public Person getFarmer() {
return farmer;
}
public void setFarmer(Person farmer) {
this.farmer = farmer;
}
public Animal getWolf() {
return wolf;
}
public void setWolf(Animal wolf) {
this.wolf = wolf;
}
public Animal getSheep() {
return sheep;
}
public void setSheep(Animal sheep) {
this.sheep = sheep;
}
public Animal getRabbit() {
return rabbit;
}
public void setRabbit(Animal rabbit) {
this.rabbit = rabbit;
}
public Plant getCabbage() {
return cabbage;
}
public void setCabbage(Plant cabbage) {
this.cabbage = cabbage;
}
public Plant getCarrot() {
return carrot;
}
public void setCarrot(Plant carrot) {
this.carrot = carrot;
}
public Boat getBoat() {
return boat;
}
public void setBoat(Boat boat) {
this.boat = boat;
}
public ArrayList<MaterialObject> getObjects() {
return objects;
}
public void setObjects(ArrayList<MaterialObject> objects) {
this.objects = objects;
}
}
package shiyan4_2;
import java.util.ArrayList;
public class GameOverRule extends AbstractRule
{
//判断游戏是否结束
@Override
public boolean judge(ArrayList<MaterialObject> objects)
{
ObjectExistRule exist=new ObjectExistRule();
CrossRiverRule cross=new CrossRiverRule();
if(!exist.judge(objects)) return true; //如果有动物死亡,则游戏结束
if(!cross.judge(objects)) return false; //如果有物体还没有过河,则物体还没结束
return true;
}
}package shiyan4_2;
import java.util.ArrayList;
public class GameSuccessRule extends AbstractRule
{
//判断游戏是否成功
@Override
public boolean judge(ArrayList<MaterialObject> objects)
{
ObjectExistRule exist=new ObjectExistRule();
CrossRiverRule cross=new CrossRiverRule();
//如果有物体没有过河或者有物体死亡,则游戏失败
if(!exist.judge(objects)) return false;
if(!cross.judge(objects)) return false;
return true;
}
}
package shiyan4_2;
import java.util.ArrayList;
import java.util.Scanner;
public class GameUI //显示界面的类
{
Scanner sc=new Scanner(System.in);
public int menu1()
{
int choice;
System.out.println("嘿嘿,欢迎你来玩农夫过河的游戏!");
while(true)
{
System.out.println("请选择操作");
System.out.println("==========1.将物体装上船============");
System.out.println("==========2:将物体卸下船=============");
System.out.println("==========3:让我看看船上有哪些物体============");
System.out.println("==========4:让我看看各物体当前的状态============");
System.out.println("==========5:过河!!!============");
System.out.println("==========6:初始化游戏重新开始玩============");
System.out.println("==========0:不想玩了,结束吧!=============");
System.out.println("请气宇轩昂的你选择一项选项吧!(0-6):");
choice = sc.nextInt();
if (choice<0||choice>6)
{
System.out.println("不要捣乱啊,请选择合适的选项!");
}
else
{
return choice;
}
}
}
public int menu2()
{
int choice;
while(true)
{
System.out.println("==========1.小小灰太狼============");
System.out.println("==========2:小小喜羊羊=============");
System.out.println("==========3:小小大白兔============");
System.out.println("==========4:小小大白菜============");
System.out.println("==========5:小小胡萝卜============");
System.out.println("==========6:返回上一级菜单============");
System.out.println("==========0:不想玩了,结束吧!=============");
System.out.println("=============================");
System.out.println("请气宇轩昂的你选择一项选项吧!(0-6):");
choice=sc.nextInt();
if(choice<0&&choice>6)
{
System.out.println("不要捣乱啊,请选择合适的选项!");
}
else
{
return choice;
}
}
}
//显示状态
public void showStatus(ArrayList<MaterialObject> objects)
{
for(MaterialObject object: objects)
{
object.showStatus();
}
}
}
package shiyan4_2;
public interface Happy
{
public abstract void happy();
}
package shiyan4_2;
public class helloworld
{
public static void main(String[] args)
{
int num=0;
while(num==0)
{
System.out.println("游戏已初始化!");
Game game = new Game();
num=game.play();
}
}
}
package shiyan4_2;
public abstract class MaterialObject implements Cry,Happy
{
private String type;
private String place;
private boolean isExist;
public MaterialObject()
{
}
public MaterialObject(String type, String place, boolean isExist)
{
this.type = type;
this.place = place;
this.isExist = isExist;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public boolean isExist() {
return isExist;
}
public void setExist(boolean exist) {
isExist = exist;
}
//该物体死翘翘
public void diedOut()
{
this.isExist=false;
}
// 显示状态
public void showStatus()
{
System.out.println(type+": 过河状态:"+place+"; 存活情况:"+(isExist?"还活着":"死了"));
}
@Override
public void cry()
{
System.out.println("农夫去哪了啊o(╥﹏╥)o,终究是成为了别人的盘中餐,唉!");
}
@Override
public void happy()
{
System.out.println("啊嚯嚯嚯,我感觉这东西很美味!٩(๑❛ᴗ❛๑)۶");
}
@Override
public boolean equals(Object obj)
{
if(obj instanceof MaterialObject object)
{
return this.type.equals(object.type)&&this.place.equals(object.place)
&&this.isExist== object.isExist;
}
else return false;
}
}
package shiyan4_2;
import java.util.ArrayList;
public class ObjectExistRule extends AbstractRule
{
//判断所有生物是否都存在
@Override
public boolean judge(ArrayList<MaterialObject> objects)
{
for (MaterialObject object:objects)
{
if(object.isExist()==false) return false;
}
return true;
}
}
package shiyan4_2;
public class Person extends MaterialObject
{
public Person() {
}
public Person(String type, String place, boolean isExist) {
super(type, place, isExist);
}
@Override
public void happy()
{
System.out.println("终于把这几个小家伙安全带过河了!不愧是我啊!哈哈哈!");
System.out.println("就这还想难倒我?");
System.out.println("前面路还长,带着这帮小家伙继续走吧!");
System.out.println("路漫漫其修远兮,吾将上下而求索!");
}
}
package shiyan4_2;
public class Plant extends MaterialObject
{
public Plant() {
}
public Plant(String type, String place, boolean isExist) {
super(type, place, isExist);
}
}
标签:java,object,System,实验,println,return,public,out From: https://www.cnblogs.com/lyzliberty/p/16949414.html