目录
1.题目与思路
捕鱼达人
池塘是一个9行9列的空间,每一格最多有一条鱼。
池塘中有3种鱼:将鱼、士鱼、相鱼。
三种鱼分别有不同的移动方式:
将鱼:只能往上、下、左、右中的一个方向移动一格。
士鱼:只能往左上、右上、左下、右下一个方向移动一格。
相鱼:只能往左上、右上、左下、右下一个方向移动两格。
但是不能移动到原来已经有鱼的地方,不能移动到 Pool 之外。
如果能移动的四个方向都不为空或不在 Pool 内,则留在原地。
每次移动顺序为,从左上角到右下角。
例如,当前池塘中鱼的分布如下:
|1|0|2|0|3|
|0|0|0|0|0|
|0|4|0|0|0|
|0|0|0|0|5|
那么移动顺序为1->2->3->4->5
如果一次移动后,所有鱼都还在原地,清空池塘中所有鱼。
每一条鱼有一个价值和生命值:
将鱼:1和1
士鱼:2和2
相鱼:3和3
鱼被子弹打中后扣除子弹伤害量的生命,生命为0时死亡,从 Pool 中消失,炮台的剩余金钱增加其价值的数值。
子弹分三种:
普通子弹:只能打中目标位置的鱼,伤害为1,消耗金钱1。
十字子弹:能打中目标位置和目标位置上下左右一格的鱼,伤害为1,消耗金钱5。
叉号子弹:能打中目标位置和目标位置上左,上右,左下,右下一格的鱼,伤害为1,消耗金钱为5。
炮台可以改变当前子弹类型,或者对某个位置发射子弹。
池塘初始鱼数目和最大数目为n=5,类型和位置随机初始化,玩家可以消耗20金钱使n加1,但是最大为10。每次玩家进行一次操作(更换子弹类型,发射子弹,增加了鱼塘最大鱼数量),就使鱼移动一次,如果当前池塘中鱼的数量
少于最大数量,就在池塘的边缘部分(第一行或第一列或第八行或第八列)随机生成一条鱼。
炮台金钱变为0时结束程序,输出失败结果,
金钱变为1000时结束程序,输出成功结果。
这个题目里面,总共出现了3个对象,池子,鱼和子弹,我们可以用array list表来存储鱼和进行打印。
类和包如下
2.创造对象和接口,完善函数。
子弹
public class Bullet implements BulletInterface {
int Power;//伤害
int Consume;//消耗的金钱
String Type;//子弹的种类
public Bullet() {
}
public Bullet(int power, int consume, String type) {
Power = power;
Consume = consume;
Type = type;
}
public void setPower(int power) {
Power = power;
}
public int getConsume() {
return Consume;
}
public void setConsume(int consume) {
Consume = consume;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
@Override
public int getPower() {
return Power;
}
/**
* 返回子弹打到第 row 行, 第 col 列时,被波及的点
* @param row
* @param col
* @return
*/
@Override
public MyPoint[] getAimedPoints(int row, int col) {
return new MyPoint[0];
}
}
/**
* 炮台
*/
public interface BatteryInterface {
/**
* 获取剩余的金钱数
* @return
*/
int getLeftMoney();
/**
* 花费 money
* 只有剩余金钱数大于等于 money 才能花费
* @param money
*/
void reduceMoney(int money);
/**
* 获取 money
* @param money
*/
void gainMoney(int money);
/**
* 设置当前使用的 bullet
* @param bullet
*/
void setBullet(Bullet bullet);
/**
* 获取当前使用的 bullet
*/
Bullet getBullet();
/**
* 向第 row 行, 第 col 列发出当前使用的子弹
* @param row
* @param col
*/
void shoot(int row, int col);
鱼
import java.util.Random;
public class Fish extends MyPoint implements FishInterface {
private int HP;//血量
private int Value;//价值
private MyPoint location;//位置
public Fish() {
}//无参数的构造
public int getHP() {
return HP;
}
public void setHP(int HP) {
this.HP = HP;
}
public void setValue(int value) {
Value = value;
}
//构造方法
/**
* 移动,根据自己的移动规则,移动到一个空位置
*
* @return 是否移动了
*/
@Override
public boolean move() {
Random r = new Random();
int number = r.nextInt(4) + 1;
if (HP == 1) {
if (number == 1) {
this.setRow(this.getRow() - 1);
this.setCol(this.getCol());
}
if (number == 2) {
this.setRow(this.getRow() + 1);
this.setCol(this.getCol());
}
if (number == 3) {
this.setRow(this.getRow());
this.setCol(this.getCol() - 1);
}
if (number == 4) {
this.setRow(this.getRow());
this.setCol(this.getCol() + 1);
}
}
if (HP == 2) {
if (number == 1) {
this.setRow(this.getRow() - 1);
this.setCol(this.getCol() - 1);
}
if (number == 2) {
this.setRow(this.getRow() - 1);
this.setCol(this.getCol() + 1);
}
if (number == 3) {
this.setRow(this.getRow() + 1);
this.setCol(this.getCol() - 1);
}
if (number == 4) {
this.setRow(this.getRow() + 1);
this.setCol(this.getCol() + 1);
}
}
if (HP == 3) {
if (number == 1) {
this.setRow(this.getRow() - 2);
this.setCol(this.getCol() - 2);
}
if (number == 2) {
this.setRow(this.getRow() - 2);
this.setCol(this.getCol() + 2);
}
if (number == 3) {
this.setRow(this.getRow() + 2);
this.setCol(this.getCol() - 2);
}
if (number == 4) {
this.setRow(this.getRow() + 2);
this.setCol(this.getCol() + 2);
}
}
return false;
}
@Override
public MyPoint getLocation() {
return location;
}//返回鱼的坐标
@Override
public boolean isAlive() {
if (this.HP <= 0) return false;
else {
return true;
}
}//查看是否活着
@Override
public int getValue() {
return this.Value;
}//获得价值
@Override
public void getDamage(int damage) {
this.HP = this.HP - damage;
}//接受伤害
}
public interface FishInterface {
/**
* 移动,根据自己的移动规则,移动到一个空位置
* @return 是否移动了
*/
boolean move();
/**
* 返回当前在池塘的位置
* @return
*/
MyPoint getLocation();
/**
*
* @return 是否还存活着
*/
boolean isAlive();
/**
*
* @return 鱼的价值
*/
int getValue();
/**
* 接受多少的伤害
* @return
*/
void getDamage(int damage);
}
池子
import java.util.ArrayList;
public class Pool implements PoolInterface {
int Rows;
int Cols;
ArrayList<MyPoint> Points;
//成员变量
public Pool() {
}
public Pool(int rows, int cols, ArrayList<MyPoint> points) {
Rows = rows;
Cols = cols;
Points = points;
}
public ArrayList<MyPoint> getPoints() {
return Points;
}
public void setPoints(ArrayList<MyPoint> points) {
Points = points;
}
public Pool(ArrayList<MyPoint> points) {
Points = points;
}
public void setRows(int rows) {
Rows = rows;
}
public void setCols(int cols) {
Cols = cols;
}
@Override
public int getRows() {
return Rows;
}
@Override
public int getCols() {
return Cols;
}
@Override
public Fish getAt(int row, int col) {
return null;
}
/**
* 设置第 row 行, 第 col 列的 Fish
* @param row
* @param col
*/
@Override
public void setAt(int row, int col, Fish fish) {
}
/**
* 返回 第 row 行, 第 col 列 是否为 null
* @param row
* @param col
* @return
*/
@Override
public boolean isEmpty(int row, int col) {
return false;
}
//构造方法
}
/**
* 池塘
*/
public interface PoolInterface {
/**
* 返回 Pool 的行数
* @return
*/
int getRows();
/**
* 返回 Pool 的列数
* @return
*/
int getCols();
/**
* 返回在第 row 行, 第 col 列的 Fish
* 如果指定位置没有 Fish 则返回 null
* @param row
* @param col
* @return
*/
Fish getAt(int row, int col);
/**
* 设置第 row 行, 第 col 列的 Fish
* @param row
* @param col
*/
void setAt(int row, int col, Fish fish);
/**
* 返回 第 row 行, 第 col 列 是否为 null
* @param row
* @param col
* @return
*/
boolean isEmpty(int row, int col);
}
---------------------------------------------------------------------------------------------------------------------------------然后我用菜单这个类,包含这些对象和其他数据
import java.util.ArrayList;
public class Menu implements MenuInterface {
int money;
Bullet bullet;
ArrayList<MyPoint> points;
ArrayList<Fish> list;
public Menu() {
}
public Menu(int money, Bullet bullet, ArrayList<MyPoint> points, ArrayList<Fish> list) {
this.money = money;
this.bullet = bullet;
this.points = points;
this.list = list;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public Bullet getBullet() {
return bullet;
}
public void setBullet(Bullet bullet) {
this.bullet = bullet;
}
public ArrayList<MyPoint> getPoints() {
return points;
}
public void setPoints(ArrayList<MyPoint> points) {
this.points = points;
}
public ArrayList<Fish> getList() {
return list;
}
public void setList(ArrayList<Fish> list) {
this.list = list;
}
@Override
public void printSelection() {
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("=========================");
System.out.println(" 请选择操作选项:");
}//打印选择菜单
@Override
public void printPool() {
System.out.println("====================捕鱼达人=======================");
System.out.println("0|--1----2----3----4----5----6----7----8----9---|");
for (int i = 1; i <= 9; i++) {
System.out.print(i);
for (int j = 1; j <= 9; j++) {
System.out.print("|");
;
String pt = chazhao(points, list, i, j);
System.out.print(pt);
}
System.out.println("|");
}
System.out.println("====================***制作=====================");
}//打印池子
@Override
public void printBatteryMessage() {
System.out.println("=========================");
System.out.println("剩余金钱数:" + money);
System.out.println("当前子弹种类:" + bullet.Type);
System.out.println("=========================");
}//打印玩家信息
@Override
public void printMenu() {
System.out.println("=================================================");
System.out.println(" 1.开始游戏");
System.out.println(" 0.退出游戏");
System.out.println("=================================================");
}//打印总菜单
//在(i,j)的位置看是否有这条鱼
public static String chazhao(ArrayList<MyPoint> points, ArrayList<Fish> list, int i, int j) {
for (int dexPoints = 0; dexPoints < points.size(); dexPoints++) {
for (int dexLise = 0; dexLise < list.size(); dexLise++) {
if (points.get(dexPoints).getRow() + 1 == i && i == list.get(dexLise).getRow()) {
if (points.get(dexPoints).getCol() + 1 == j && j == list.get(dexLise).getCol()) {
if (list.get(dexLise).getValue() == 1) return " 将鱼";
if (list.get(dexLise).getValue() == 2) return " 士鱼";
if (list.get(dexLise).getValue() == 3) return " 相鱼";
}
}
}
}
return " ";
}
}
public interface MenuInterface {
/**
* 输出选项菜单。
* 格式可以参考下面的:
* ================
* 1.选择普通子弹
* 2.选择十字子弹
* 3.选择叉号子弹
* 4.发出子弹
* 5.增加最大鱼条数
* ===============
* 请选择操作选项:
*/
void printSelection();
/**
* 输出当前池塘中的鱼分布情况
* 格式可以参考如下:
* ========捕鱼达人=======
* |—1——2——3——4—|
* 1|将鱼 | |士鱼 | |
* 2| | | | |
* 3|相鱼 | | | |
* 4| | | | |
* ====================
*
* 表示第1行第1列有一条将鱼,
* 第1行第3列有一条士鱼,
* 第3行1列有一条相鱼,其他地方为空
*/
void printPool();
/**
* 输出炮台剩余金钱、当前使用的子弹
* 参考如下:
*
* 剩余金钱数:100
* 当前子弹种类:十字弹
*
*/
void printBatteryMessage();
/**
* 输出所有菜单
*/
void printMenu();
}
------------------------------------------------------------------------------------------------------------------------
另外的一个类存储位置,flex用来判断是否有鱼,有的话为1,没有的话是0。
public class MyPoint {
private int row;
private int col;
private int flex;
public MyPoint() {
}
public MyPoint(int row, int col, int flex) {
this.row = row;
this.col = col;
this.flex = flex;
}
public int getRow() {
return row;
}//返回行数
public void setRow(int row) {
this.row = row;
}//设置行数
public int getCol() {
return col;
}//返回列数
public void setCol(int col) {
this.col = col;
}//设置列数
public int getFlex() {
return flex;
}
public void setFlex(int flex) {
this.flex = flex;
}
}
3.方法的实现
用switch语句来进行选择,之后写了增加鱼和移动鱼的方法。
import org.w3c.dom.ls.LSOutput;
import java.awt.*;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
//point 是坐标的位置
public class Main {
public static void main(String[] args) {
System.out.println("---------------欢迎来到捕鱼达人------------------");
System.out.println("---------------作者: ***------------------");
System.out.println();
System.out.println();//第一步,打印欢迎游戏的界面
/*加载*/
ArrayList<MyPoint> points = new ArrayList<MyPoint>();//池子的初始化
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
MyPoint a = new MyPoint(i, j, 0);
points.add(a);
}
}//flex 是判定是否有鱼儿,有的话是1,没有的话是0
//i和j分别是第几行和第几列
Pool pool = new Pool(9, 9, points);
ArrayList<Fish> list = new ArrayList<Fish>();//鱼的存储
Bullet bullet = new Bullet(1, 1, "普通子弹");
Menu menu = new Menu(600, bullet, points, list);//points是池子表,list是鱼的表
for (int i = 0; i < 5; i++) {
AddFish(list, menu);//增加初始的鱼
}
menu.printMenu();//第二步,打印总菜单
System.out.println("请输入您的选择:");
while (true) {
int choose;
Scanner sc = new Scanner(System.in);
choose = sc.nextInt();//玩家进行选择
switch (choose) {
case 1:
while (true) {
if (menu.money <= 0) {
System.out.println("你失败了,请重新来过");
break;
} else if (menu.money >= 1000) {
System.out.println("你赢了,请继续加油");
break;
}//判断游戏是否结束
int ch;
menu.printPool();//游戏界面
menu.printBatteryMessage();//背包界面,每一次都要显示界面
menu.printSelection();//操作界面
ch = sc.nextInt();
switch (ch) {
case 1:
Bullet bullet1 = new Bullet(1, 1, "普通子弹");
menu.bullet = bullet1;
MoveFish(list, menu);
break;
case 2:
Bullet bullet2 = new Bullet(1, 1, "十字子弹");
menu.bullet = bullet2;
MoveFish(list, menu);
break;
case 3:
Bullet bullet3 = new Bullet(1, 1, "叉号子弹");
menu.bullet = bullet3;
MoveFish(list, menu);
break;
case 4:
System.out.println("请输入你要攻击的坐标:");
int x = sc.nextInt();
int y = sc.nextInt();
HurtFish(list, menu, x, y);
MoveFish(list, menu);
break;
case 5:
AddFish(list, menu);
System.out.println("鱼池已经升级");
MoveFish(list, menu);
break;
case 6:
menu.money = menu.money + 100;
System.out.println("作弊码");
MoveFish(list, menu);
break;
default:
System.out.println("选择失败,请重新选择");
break;
}
}
choose = 0;
break;
case 0:
System.out.println("退出游玩");
break;
default:
System.out.println("选择失败,请重新选择");
break;
}
if (choose == 0) break;
}
}
之后来写方法。
增加鱼的方法
public static void AddFish(ArrayList<Fish> list, Menu menu) {
int count = list.size();
if (count > 10) {
System.out.println("鱼的数目已经达到最大值,增加失败");
return;
}//鱼的数量过多
Fish jiangyu = new Fish();
Fish shiyu = new Fish();
Fish xiangyu = new Fish();
jiangyu.setHP(1);
jiangyu.setValue(1);
shiyu.setHP(2);
shiyu.setValue(2);
xiangyu.setHP(3);
xiangyu.setValue(3);//鱼的种类的初始化,创造出三条鱼
int row = 0, col = 0;
Random r = new Random();
while (true) {
int flag = 1;
int number = r.nextInt(4) + 1;//生成随机数1~4
if (number == 1) {
row = 1;
col = r.nextInt(9) + 1;
}
if (number == 2) {
row = 8;
col = r.nextInt(9) + 1;
}
if (number == 3) {
col = 1;
row = r.nextInt(9) + 1;
}
if (number == 4) {
col = 8;
row = r.nextInt(9) + 1;
}
for (int i = 0; i < list.size(); i++) {
if ((list.get(i).getRow() == row) && (list.get(i).getCol() == col)) {
flag = 0;
}
break;
}//判断生成的位置是否有鱼
if (flag == 1) {
break;
}
}
int number = r.nextInt(10) + 1;//生成随机数1~10
if (number == 1) {
xiangyu.setRow(row);
xiangyu.setCol(col);
list.add(xiangyu);
} else if (number > 1 && number < 5) {
shiyu.setRow(row);
shiyu.setCol(col);
list.add(shiyu);
} else if (number >= 5) {
jiangyu.setRow(row);
jiangyu.setCol(col);
list.add(jiangyu);
}//鱼的添加
menu.money = menu.money - 20;
int dex = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (menu.points.get(dex).getRow() == row && menu.points.get(dex).getCol() == col) ;
menu.points.get(dex).setFlex(1);
dex = dex + 1;
}
}//遍历池子表,在坐标对应的地方赋值1;
return;
}//增加鱼的函数
移动鱼的方法如下
public static void MoveFish(ArrayList<Fish> list, Menu menu) {
for (int i = 0; i < list.size(); i++) {
int rol = list.get(i).getRow();
int col = list.get(i).getCol();
while (true) {
list.get(i).move();
if (list.get(i).getRow() <= 0 || list.get(i).getRow() >= 10) {
list.get(i).setRow(rol);
list.get(i).setCol(col);
continue;
}//不能移动到池子的外面
if (list.get(i).getCol() <= 0 || list.get(i).getCol() >= 10) {
list.get(i).setRow(rol);
list.get(i).setCol(col);
continue;
}//不能移动到池子的外面
int a = 0;
int j = 0;
for (j = 0; j < list.size(); j++) {
if (j == i) continue;
if ((list.get(j).getRow() == list.get(i).getRow()) && ((list.get(j).getCol() == list.get(i).getCol()))) {
list.get(i).setRow(rol);
list.get(i).setCol(col);
a = 1;//判断器
break;
}//移动的位置有鱼
}
if (a == 1) continue;//不能移动到有鱼的地方
break;
}
//rol 1~9 col 1~9
//menu.points.get((rol-1) * 9 + col-1).setFlex(0);
//menu.points.get((list.get(i).getRow()-1) * 9 + list.get(i).getCol()-1).setFlex(1);
}
}//移动鱼的函数
攻击鱼的方法如下
public static void HurtFish(ArrayList<Fish> list, Menu menu, int x, int y) {
if (menu.bullet.Type == "普通子弹") {
int hurt = menu.bullet.Power;
menu.money = menu.money - 1;
for (int i = 0; i < list.size(); i++) {
HurtFish1(list, menu, x, y, i, hurt);
}
}
if (menu.bullet.Type == "十字子弹") {
int hurt = menu.bullet.Power;
menu.money = menu.money - 5;
for (int i = 0; i < list.size(); i++) {
HurtFish1(list, menu, x, y, i, hurt);
HurtFish1(list, menu, x - 1, y, i, hurt);
HurtFish1(list, menu, x + 1, y, i, hurt);
HurtFish1(list, menu, x, y - 1, i, hurt);
HurtFish1(list, menu, x, y + 1, i, hurt);
}
}
if (menu.bullet.Type == "叉号子弹") {
int hurt = menu.bullet.Power;
menu.money = menu.money - 5;
for (int i = 0; i < list.size(); i++) {
HurtFish1(list, menu, x, y, i, hurt);
HurtFish1(list, menu, x - 1, y - 1, i, hurt);
HurtFish1(list, menu, x + 1, y + 1, i, hurt);
HurtFish1(list, menu, x - 1, y + 1, i, hurt);
HurtFish1(list, menu, x + 1, y - 1, i, hurt);
}
}
}//攻击鱼的函数
public static void HurtFish1(ArrayList<Fish> list, Menu menu, int x, int y, int i, int hurt) {
if (list.get(i).getRow() == x && list.get(i).getCol() == y) {
list.get(i).getDamage(hurt);
if (!list.get(i).isAlive()) {
System.out.println("攻击成功,击杀鱼" + "(" + x + "," + y + ")");
list.remove(i);
AddFish(list, menu);
menu.money = menu.money + 20;
menu.money = menu.money + list.get(i).getValue();
} else {
System.out.println("攻击成功,这条鱼" + "(" + x + "," + y + ")" + "还有HP:" + list.get(i).getHP());
}
return;
}
return;
}
一个综合案例就这样写完了,其中的思路都很重要,要理清楚对象之间的关机。运行结果:
输入4
输入8 1
谢谢观看,总共1000行代码