I start to create battleship game in java. I have 5 ships with length 5,4,3,3,2 and an array int gameBoard[][] = new int[10][10]; where i put the ships. I also create an array boolean BoardHits[][]= new boolean[10][10]; where i check the hits of the player.
Now i want to create a method boolean getBoardStrike(int[] hit) which takes as parameter a position and adds a hit at BoardHits array if this position has not been hitted again. If we hit a ship the we must check if all ship positions hitted(ship sank). Are there any efficient way to implement this?
(When i put a ship in the array gameBoard i put the ship id, so if i a ship with length 5 in the board i have 5 cells with the number 5).
public boolean getBoardStrike(int[] hit) {
boolean flag = true;
if (boardHits[hit[0]][hit[1]] = false) {
hits[hit[0]][hit[1]] = true;
//check if the whole ship is hitted
return true;
}
else {
return false;
}
}
I would try more object oriented approach since Java is object-oriented language:
public interface Battleship {
public void hit(Point shot);
public List<Point> getCoordinates();
public boolean isSinked();
}
public class BattleshipPart {
private boolean hit;
private Point coordinate;
// getters and setters
}
public abstract class AbstractBattleship implements Battleship {
// these are for direction in constructors
public static int NORTH = 1;
public static int EAST = 2;
public static int SOUTH = 3;
public static int WEST = 4;
protected List<BattleshipPart> parts;
public void hit(Point shot) {
return parts.stream()
.findFirst(part -> part.coordinate.equals(shot))
.ifPresent(part -> part.setHit(true));
}
public List<Point> getCoordinates() {
return parts.stream()
.map(part -> part.getCoordinate())
.collect(Collectors.toList());
}
public boolean isSinked() {
return parts.stream()
.allMatch(BattleshipPart::isHit);
}
}
public final class SmallBattleship extends AbstractBattleship {
public SmallBattleship(Point start, int direction) {
// create parts or throw exception if parameters weren't valid
}
}
New ship types are created just by extending AbstractBattleship and just creating new parts in constructor.
Related
I am able to find the card I want in passCard() but I been stumped on moving that card into the hand.
public class CardContainer
{
protected Card[] cards;
this is where i am trying to pass the card i find into the hand. i am able to find the card but been stuck after that.
public boolean passCard(CardContainer cc, Card c)
{
for(int i = 0; i < cards.length; i++)
{
if(cards[i].equals(c))
{
//this is where im trying to make magic happen
return true;
}
}
return false;
}
}
public class Hand extends CardContainer {
private String playerName;
public Hand(String name, int numCards)
{
playerName = name;
cards = new Card[numCards];
// manually entered a card to test if it works
cards[1] = new Card(1,'s');
}
}
public class TestDemo {
public static void main(String[] args) {
Hand h = new Hand("name", 10);
System.out.println(deck.passCard(h, new Card(2,'s')));
// prints manually entered card in hand class
h.printCards();
}
In your passCard function you can simply initialize an element in Cards (This is assuming you want to initialize it at position i):
public boolean passCard(CardContainer cc, Card c)
{
for(int i = 0; i < cards.length; i++)
{
if(cards[i].equals(c))
{
h.cards[i] = this.cards[i];
return true;
}
}
return false;
}
Since cards is only protected:
The protected modifier specifies that the member can only be accessed within its own package
Meaning that your Hand class can access it.
I am making a checkers game and have the following classes.
Abstract class piece:
public abstract class Piece {
protected Position position;
private CheckersColor color;
public Piece(CheckersColor color, Position position) {
this.position = position;
this.color = color;
}
with some more methods.
The sub class Checker:
public class Checker extends Piece {
public Checker(CheckersColor color, Position position) {
super(color, position);
}
with also some more methods, and another sub class king:
public class King extends Piece {
public King(CheckersColor color, Position position) {
super(color, position);
}
public King(Piece checker) {
super(checker.getColor(), checker.position);
}
The checkers are stored in an array of type Piece
private Piece[] whiteCheckers;
and inserted by :
whiteCheckers[counter] = new Checker(Constants.COLOR_WHITE, tempPosition);
So far everything works, but when I try to change one of the checkers into a king I get an error:
Exception in thread "main" java.lang.ArrayStoreException: King
The code that causes the error:
whiteCheckers[i] = new King(piece);
I have tried a few different ways to store it, with casting, removing the checker and adding the king in the same spot and more with no luck.
That's really weird to me because the checkers were stored with no problem and king causes the error while they are both sub classes of Piece.
Thanks a lot!
EDIT:
public class Board {
private int size;
private Piece[] blackCheckers;
private Piece[] whiteCheckers;
private Piece[][] board;
public Board(int size) {
....(Some other code)
for (int k = 0; k < whiteCheckers.length; k++) {
board[whiteCheckers[k].position.getRow()][whiteCheckers[k].position.getColumn()] = whiteCheckers[k];
board[blackCheckers[k].position.getRow()][blackCheckers[k].position.getColumn()] = blackCheckers[k];
}
} else {
throw new RuntimeException("The size is either smaller than 4 or is not even");
}
}
....(Some more methods)
public void verifyCrown(Piece piece) {
if ((piece.getColor().equals(Constants.COLOR_WHITE) && piece.position.getRow() == 0)
|| piece.getColor().equals(Constants.COLOR_BLACK) && piece.position.getRow() == size - 1) {
if (piece.getColor().equals(Constants.COLOR_WHITE)) {
for (int i = 0; i < whiteCheckers.length; i++) {
if (whiteCheckers[i].equals(piece)) {
whiteCheckers[i] = new King(piece);
}
}
}
if (piece.getColor().equals(Constants.COLOR_BLACK)) {
for (int i = 0; i < blackCheckers.length; i++) {
if (blackCheckers[i].equals(piece)) {
blackCheckers[i] = new King(piece);
}
}
}
....
}
}
}
Can you please show us how the array is initialized?
The cause could be that you initialize the array as follows:
Piece[] whiteCheckers = new Checker[n];
instead of
Piece[] whiteCheckers = new Piece[n];
which would not allow you to add objects of type King to it.
But again without seeing how the array was initialized, this may not be the case.
I am using Greenfoot IDE and i have a World Class and a Boat class and a Exit class
Inside the Boat class i have a constructor which defines the boat (what kinda boat it is & which picture).
Boat Code:
public class Boat extends Actor
{
private int size;
private int speed;
private int slow = 1;
private boolean leeg = false;
private int id;
private int time;
public void act() {
MoveBoat();
MoveMouse();
ExitHarbor(time);
Dock();
Colission();
}
public Boat(int newSize, int i, int t) {
size = newSize;
id = i;
time = t;
setImage(id);
}
public void setImage(int i) {
if (!leeg) {
setImage(new GreenfootImage("Boat"+i+".png"));
}
else {
setImage(new GreenfootImage("Boatleeg"+i+".png"));
}
}
}
Inside the Exit class I have a constructor which defines the different Exit's
Exit:
public class Exit extends Actor
{
private String color;
private int points;
/**
* Act - do whatever the Exit wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public Exit(String kleur) {
color = kleur;
setImage(kleur);
}
public void setImage(String kleur) {
//Game1 game = getWorld().getObjects(Boat.class);
setImage(new GreenfootImage("exit"+kleur+".png"));
}
public String getColor()
{
return color;
}
}
In the World class i added 3 different boats & 3 different exits to the so called "World" of greenfoot with different parameters. Now i have 3 different boats & 3 different Exits.
World:
public class Game1 extends World
{
/**
* Constructor for objects of class Game1.
*
*/
public Game1()
{
// Create a new world with 600x400 cells with a cell size of 1x1 pixels.
super(900, 900, 1);
prepare();
}
public void prepare()
{
Exit exit1 = new Exit("paars");
addObject(exit1, 885, 615);
Exit exit2 = new Exit("groen");
addObject(exit2, 885, 472);
Exit exit3 = new Exit("geel");
addObject(exit3, 885, 340);
Boat boat1 = new Boat(10,1,700);
addObject(boat1, 500,61);
Boat boat2 = new Boat(20,2,500);
addObject(boat2, 800,61);
Boat boat3 = new Boat(30,3,300);
addObject(boat3, 650,61);
}
}
The problem I'm having at the moment is that i wan't to specify 1 boat to 1 exit. To clear it more i wan't that boat 1 can only interact with the "geel" Exit (or exit1).
I already tried some code but i can't get it to work.
Tried code:
if (id == 1 && "geel".equals(exit.getColor()))
I think i can make it work with this if but for that i need to retrieve the objects from the World class or from the Boat class, I don't know how to do it? i tried
Actor boat = (Actor)getWorld().getObjects(Boat.class).get(0);
But that doesn't return the 3 different Boats (including their object(variable) names)
Anyone any suggestions?
p.s It is more code but i only showed the code which is necesarry for this problem
after The reactions i tried some but I'm stuck again`
public void ExitBoat(Exit exit, int size) {
this.exit = exit;
System.out.println(exit);
/* if(exit == exit1 && size == 10) {
System.out.println("jdjdf");
}*/
}
public Boat(Exit uitgang, int newSize, int i, int t) {
exit = uitgang;
size = newSize;
id = i;
time = t;
setImage(id);
}
now I'm stuck again i dont know how to call the method with the right parameters in my public void act.
You could add Exit as a field in the Boat class
private Exit exit;
add the exit to Boats constructor so you can create the Boat instances like this.
Boat boat1 = new Boat(exit1, 10,1,700);
I want to spawn my item (Sword1) in random places. When i spawn it, first of all it only creates 1 of it, then it moves randomly everywhere. Should I create and array for the object? How?
public class Sword1 {
public static TextureRegion sprite;
public static int x;
public static int y;
public static int size;
public static boolean created;
public Sword1(){
created=true;
Random r = new Random();
x = (r.nextInt(5)+1)*GameRender.tilesize;
y = (r.nextInt(5)+1)*GameRender.tilesize;
size = GameRender.tilesize;
sprite = AssetLoader.s1;
createMe();
}
public static void createMe() {
GameRender.batch.draw(sprite, x, y, size, size);
}
}
I render it in batch:
while(number<4){
number++;
Items.createSwords();
}
I also tried to use Items class that would hold all the Items when there would be more
public class Items {
public Items(){}
public static void createSwords() {
Object sword = (Sword1) new Sword1();
}
}
You can clean up and rename a bit the Sword1 class [I also changed the static variables to private] otherwise they will be shared across the various class instances see: Static Variables — What Are They?.
public class Sword {
private TextureRegion sprite;
private int x;
private int y;
private int size;
public Sword() {
Random r = new Random();
x = (r.nextInt(5)+1)*GameRender.tilesize;
y = (r.nextInt(5)+1)*GameRender.tilesize;
size = GameRender.tilesize;
sprite = AssetLoader.s1;
}
public void createMe() {
GameRender.batch.draw(sprite, x, y, size, size);
}
}
Then to have multiple swords you can use and an ArrayList of Swords the class that is using the Sword object GameRender as given in comment:
private List<Sword> swords = new ArrayList<Sword>();
for more info on Array see the Oracle documentation
Now you would have a List of Swords objects. This list will be used to store the newly create Sword objects and to render them later.
create swords
//create 10 swords
for (int i = 0; i<10 ; i++ ) {
swords.add(new Sword());
}
render swords , call the create method in each object
for (Sword sword : swords) {
sword.createMe();
}
for example a minimal example in the GameRender Class
public class GameRender() {
private List<Sword> swords = new ArrayList<Sword>();
public GameRender(){
// create the swords
for (int i = 0; i<10 ; i++ ) {
swords.add(new Sword());
}
// render the swords
public void render() {
for (Sword sword : swords) {
sword.createMe();
}
}
}
I am trying to add weapons to a player inventory. It's kind of hard to explain, so I'll try my best. What I have are a class for each weapon, a class for Combat, and a class for the Player. I am trying to get it to where when the Random number equals a certain number, it will add a weapon to the player inventory. I will put my code Below.
Combat Class:
public class Combat {
M4 m4 = new M4();
M16 m16 = new M16();
M9 m9 = new M9();
Glock glock = new Glock();
SCAR Scar = new SCAR();
Player player = new Player();
final int chanceOfDrop = 3;
static boolean[] hasWeapon = {false, true};
public static int ranNumberGen(int chanceOfDrop) {
return (int) (Math.random()*5);
}
private void enemyDead() {
boolean canDrop = false;
if(ranNumberGen(chanceOfDrop)==0){
canDrop = true;
}
if(canDrop == true){
if(ranNumberGen(0) == 1) {
Player.addInvetory(m4.weaponName(wepName), m4.weaponAmmo(wepAmmo)); //Issues here. wepName & wepAmmo cannot be resolved into variable
//Should I just delete the line?
//Trying to get it to add the weapon M4 to the player inventory.
//Maybe use an ArrayList? If so I need a couple pointers on how to implement this.
}
}
}
}
M4 Class:
public class M4 implements Armory {
//Weapon classes are practically identical except for differences in the name wepDamage and wepAmmo.
public Integer weaponAmmo(int wepAmmo) {
wepAmmo = 10;
return wepAmmo;
}
public Integer weaponDamage(int wepDamage) {
wepDamage = 5;
return wepDamage;
}
public String weaponName(String wepName) {
wepName = "M4";
return wepName;
}
Player Class:
public class Player {
public static int health = 100;
//Player Class.
public static void addInvetory(String wepName, int wepAmmo) {
Player.addInvetory(wepName, wepAmmo);
}
public static void removeInventory(String wepName, int wepAmmo) {
Player.addInvetory(wepName, wepAmmo);
}
public static void removeAll(String wepName, int wepAmmo) {
Player.removeAll(wepName, wepAmmo);
}
Interface:
public interface Armory {
//Interface implemented by all of the weapons classes.
public Integer weaponAmmo(int wepAmmo);
public Integer weaponDamage(int wepDamage);
public String weaponName(String wepName);
Hope you can help!
class Weapon {
private final String name;
private final int damage;
private final int ammo;
public Weapon(final String name,final int damage,final int ammo) {
this.name = name;
this.damage = damage;
this.ammo = ammo;
}
public Weapon clone() {
return new Weapon(this.name,this.damage,this.ammo);
}
public String getName() {
return this.name;
}
public int getAmmo() {
return this.ammo;
}
public int getDamage() {
return this.damage;
}
}
class WeaponFactory {
static WeaponFactory factory;
public static WeaponFactory getWeaponFactory() {
if(factory == null) {
factory = new WeaponFactory();
}
return factory;
}
private ArrayList<Weapon> weapons = new ArrayList<Weapon>();
private Random random;
private WeaponFactory() {
//TODO: Fix Ammo and Damage
weapons.add(new Weapon("M4",0,0));
weapons.add(new Weapon("M16",0,0));
weapons.add(new Weapon("M9",0,0));
weapons.add(new Weapon("Glock",0,0));
weapons.add(new Weapon("SCAR",0,0));
}
public Weapon getWeapon() {
int w = random.nextInt(weapons.length);
return weapons.get(w).clone();
}
}
class Combat {
...
private void enemyDead() {
if(ranNumberGen(chanceOfDrop)==0){
Player.addInventory(WeaponFactory.getWeaponFactory().getWeapon());
}
}
}
You can use an array of Armory and the generate a random number from 0 to the size of the array as an index to the array to decide which weapon to add.
Okay dude, since your question about creating a programming language was closed, I'm answering it through here:
I think that your idea is great! Don't give up on it, yet don't get too excited. I would try all the options that you have heard of(interpreted route AND the Compiled route). If you can get either of those to work, then you may proceed to go into further detail with the language creation. It's going to take a while though. Be patient!