Commit 66c817f2 authored by Anya Helene Bagge's avatar Anya Helene Bagge 🦆

kopi fra f17

parent d804d524
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>inf101v16f19</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
package inf101.dyr;
import inf101.grid.Direction;
import inf101.grid.IPosition;
import inf101.grid.Position;
public abstract class Dyr {
private double masse;
IPosition pos;
Direction dir;
public Dyr(double m) {
masse = m;
pos = Position.make(0, 0);
dir = Direction.NORTH;
// problem: hvis checkState er overstyr i subklasser, så blir
// subklassens checkState kalt *før* subklassens konstruktør er
// ferdig med å lage et gyldig objekt
checkState();
}
public double getMass() {
return masse;
}
public IPosition getPosition() {
return pos;
}
public void move() {
pos = pos.go(dir);
checkState();
}
public void hei() {
System.out.println("Hei, jeg er en " + toString() + " på posisjon " + pos + " og jeg veier " + masse + "g");
}
public String toString() {
return "dyr";
}
/**
* Må være >= 0, og >= {@link #getMinMat()}
*
* @return Maksimal mengde vekt man kan gi til {@link #spis(double)}
*/
public double getMaxMat() {
return 0.5*getMass();
}
/**
* Må være >= 0, og <= {@link #getMaxMat()}
* @return Minste mengde vekt man kan gi til {@link #spis(double)}
*/
public double getMinMat() {
return 1;
}
/**
* Dyret spiser litt, og blir større
*
* @param vekt Mengde mat dyret skal spise
*
* Forkrav: vekt må være positiv, større enn getMinMat(), og mindre enn getMaxMat()
*
* Garanterer at getMass() øker med 0.05*vekt
*/
public void spis(double vekt) {
if(vekt < getMinMat() || vekt > getMaxMat())
throw new IllegalArgumentException("For mye mat!");
System.out.println("Jeg spiser som et dyr!");
this.masse += vekt/10;
checkState();
}
public abstract Dyr kopi();
/**
* Sjekk datainvariant
*
* @throws IllegalStateException hvis objektet har ulovlig tilstand
*/
public void checkState() {
if(masse <= 0.0 || Double.isNaN(masse) || Double.isInfinite(masse))
throw new IllegalStateException();
if(pos == null)
throw new IllegalStateException();
if(dir == null)
throw new IllegalStateException();
}
protected void setMasse(double newMasse) {
if(newMasse <= 0.0)
throw new IllegalArgumentException();
masse = newMasse;
// checkState();
}
}
package inf101.dyr;
import inf101.grid.Direction;
public class Kanin extends Dyr {
private double tannLengde;
public Kanin() {
super(3500.0);
tannLengde = 10.0;
checkState();
}
@Override
public String toString() {
return "kanin";
}
@Override
public void move() {
pos = pos.go(Direction.EAST);
checkState();
}
public void spis(double vekt) {
System.out.println("Jeg spiser som en kanin!");
if(vekt < getMinMat())
throw new IllegalArgumentException("For lite mat");
// vi har et løsere forkrav, aksepterer opptil 1.0* massen
if(vekt > getMass())
throw new IllegalArgumentException("For stor porsjon!");
double oldMasse = getMass();
// vi er mer effektive, legger på oss like mye som vi spiser
setMasse(getMass() + vekt);
// dette var minstekravet
assert getMass() >= 1.05*oldMasse;
checkState();
}
@Override
public Kanin kopi() {
Kanin kopi = new Kanin();
kopi.dir = dir;
kopi.setMasse(getMass());
kopi.pos = pos;
kopi.checkState();
return kopi;
}
public void checkState() {
System.out.println("Kanins checkState");
super.checkState();
if(tannLengde <= 0.0)
throw new IllegalStateException();
}
}
package inf101.dyr;
import inf101.grid.IGrid2D;
public class MainDyr {
public static void main(String[] args) {
Dyr d = new Kanin(); // kan ikke lage objekter av Dyr :(
Kanin k = new Kanin();
Ulv u = new Ulv();
Dyr v = new Ulv();
d.hei();
u.hei();
v.hei();
k.hei();
k.move();
u.move();
k.hei();
u.hei();
k.spis(15);
u.spis(30);
k.hei();
u.hei();
System.out.println();
Dyr dk = k;
Dyr du = u;
// Hvis spis() ikke finnes i Dyr, så må vi typekonvertere
// hvis vi vil kalle spis, selv om alle dyrene kan spise
// ((Ulv) du).spis(50);
du.spis(50);
du.hei();
u.spis(50);
u.hei();
System.out.println();
dk.spis(40.0);
k.spis(40);
k.spis(40.0);
Kanin kopi = k.kopi();
Dyr kopi2 = dk.kopi();
if(kopi2 instanceof Kanin) // alltid sant her...
;
//u.spis(-50000);
k.spis(-50000);
}
}
package inf101.dyr;
public class Ulv extends Dyr {
public Ulv() {
super(30000.0);
}
@Override
public String toString() {
return "ulv";
}
@Override
public void spis(double vekt) {
System.out.println("GRRRROAAOAO");
double oldMasse = getMass();
// super.spis(vekt);
// bryter Liskovs substitusjonsprinsipp: her har vi strenger
// krav til parameterne enn superklassen har :(
if(vekt > 0.1*getMass())
throw new IllegalArgumentException("blueergh!!");
// bryter også prinsippet, her øker vi massen for lite
// i forhold til parameteret.
setMasse(getMass() + vekt * 0.01);
// dette var minstekravet
assert getMass() >= 1.05*oldMasse;
checkState();
}
@Override
public Ulv kopi() {
Ulv ulv = new Ulv();
ulv.dir = dir;
ulv.setMasse(getMass());
ulv.pos = pos;
ulv.checkState();
return ulv;
}
}
package inf101.games;
/**
* Abstrakt superklasse for spill, som implementerer en del av av de enkle
* metodene.
*
* @author Anya Helene Bagge
*
*/
public abstract class AbstractGame implements IGame {
private int width;
private int height;
@Override
public boolean canChangeSize() {
return false;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
}
package inf101.games;
import inf101.games.gui.IImage;
import inf101.games.gui.IUserInterface;
import inf101.grid.IPosition;
import java.util.List;
/**
* Interface for brettspill som passer til brettspill-GUIen
*
* Spillene er ment å bli kontrollert av GameGUI-en, som kaller metodene
* definert under basert på knappene som brukerne trykker på.
*
* En del av metodene styrer oppsettet til GameGUI-en ved å, f.eks., velge hvor
* vidt enkelte knapper skal være skrudd på, eller hvilke menyvalg som finnes.
*
* @author Anya Helene Bagge
*
*/
public interface IGame {
/**
* @return True hvis spillet kan endre størrelse uten at man kaller
* newGame() etterpå
*/
boolean canChangeSize();
/**
* Returnerer brettstørrelse-valg til menyen.
*
* Hver størrelse må strenger være på formen "WxH", der W og H er heltall.
*
* @return En liste med brettstørrelser, eller null for å bruke standard
* størrelser.
*/
List<String> getBoardSizes();
/**
* @return Height of a game cell, in pixels. (>= 1)
*/
int getCellHeight();
/**
* @return Width of a game cell, in pixels. (>= 1)
*/
int getCellWidth();
/**
* @return Høyden på spillet, i felter. (>= 1)
*/
int getHeight();
IImage getImageAt(IPosition pos);
/**
* Egne menyvalg for spillet.
*
* Denne metoden skal returnere enten null, hvis spillet ikke skal ha sin
* egen meny, eller en liste med menyvalg for spillet.
*
* @return En liste med menyvalg til en egen spill-meny, eller null hvis
* spillet ikke har sin egen meny.
*/
List<String> getMenuChoices();
/**
* @return Navnet på spillet
*/
String getName();
/**
* @return Bredden på spillet, i felter. (>= 1)
*/
int getWidth();
/**
* Initialise the game board.
*
* Should set up the game logic as necessary to begin a new game.
*
* Any previous state is lost.
*
*/
void newGame();
/**
* Kalles når spilleren har gjort et menyvalg i GameGUI-en.
*
* @param s
* En streng som tidligere er returnert fra getMenuChoices()
* @throws UnsupportedOperationException
* hvis spillet ikke har sin egen meny
*/
void setMenuChoice(String s);
/**
* Sett størrelsen på spillet.
*
* MERK: hvis spillet av en eller annen grunn ikke kan ha den gitt
* bredden/høyden, blir den nye bredden/høyden uendret, eller et sted mellom
* den gamle og den ønskede nye bredden/høyden. Sjekk alltid getWidth() /
* getHeight() etter å ha kalt setSize().
*
* Det kan være nødvendig å kalle newGame() etterpå for at spillet skal
* virke – i såfall vil canChangeSize() returnere false.
*
* @param width
* Ønsket ny bredde
* @param height
* Ønsket ny høyde
* @throws IllegalArgumentException
* hvis width eller height er mindre enn 1
*/
void setSize(int width, int height);
/**
* Set up the game's connection to the user interface.
*
* This method should set up listeners to receive time and mouse click
* events, configure the user interface, and so on.
*
* {@link #newGame()} will be called after this method, so there is no need
* to set up game logic here.
*
* @param ui
* A user interface
*/
void setup(IUserInterface ui);
}
package inf101.games;
import inf101.games.gui.GUIFrame;
import inf101.games.gui.GameGUI;
import inf101.games.life.Life;
import inf101.games.minesweeper.Minesweeper;
import inf101.games.simgame.SimGame;
import inf101.games.zombiesweeper.Zombiesweeper;
import java.util.Arrays;
public class Main101Games /* extends JApplet */ {
// private static final long serialVersionUID = -5830018712727696869L;
public static void main(String[] args) {
new GUIFrame(startGame());
}
public static GameGUI startGame() {
IGame life = new Life(15, 17);
IGame sweeper = new Minesweeper(15, 17);
IGame zombie = new Zombiesweeper(15, 17);
IGame simgame = new SimGame(15, 17);
return new GameGUI(Arrays.asList(simgame, sweeper, zombie, life));
}
/*
@Override
public void init() {
final JApplet applet = this;
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
GameGUI game = startGame();
applet.add(game);
game.initialize();
}
});
} catch (InterruptedException e) {
// Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
*/
}
package inf101.games.gui;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
public class AnimatedImage implements IImage {
public static final int ANIMATION_BASE_DELAY = 16;
private List<ImageIcon> icons;
private int numFrames;
private int repeat;
private int delay;
private int frame;
private int lastFrame;
private int tick;
/**
* Create an animated image. NumFrames indicates how many frames are in the
* animation, which will be constructed from image files names
* "&lt;basename&gt;-0", "&lt;basename&gt;-1", ... up to
* &lt;numFrames-1&gt;.
*
* For example: jump-0.jpg, jump-1.jpg, jump-2.jpg, for basename="jump" and
* numFrames=3.
*
* @param baseName
* Base name of image files
* @param numFrames
* Number of frames (must be >= 1)
* @param delay
* Delay between each image, in milliseconds (will be rounded to
* nearest non-zero increment of {@value #ANIMATION_BASE_DELAY}
* ms)
* @param repeat
* Number of times to repeat the animation, 0 for infinite
*/
public AnimatedImage(String baseName, int numFrames, int delay, int repeat) {
if (numFrames < 1) {
throw new IllegalArgumentException(
"Number of frames must be one or greater");
}
if (delay < 0)
throw new IllegalArgumentException("Delay must be 0 or greater");
if (repeat < 0)
throw new IllegalArgumentException("Repeat must be 0 or greater");
this.numFrames = numFrames;
this.delay = Math.max(1, delay / ANIMATION_BASE_DELAY);
if (repeat == 0)
repeat = -1;
this.repeat = repeat*this.delay*this.numFrames;
this.frame = 0;
this.lastFrame = -1;
this.icons = new ArrayList<ImageIcon>();
for (int i = 0; i < numFrames; i++) {
icons.add(ImageLoader.getImage(baseName + "-" + i));
}
this.tick = -1;
}
private AnimatedImage(List<ImageIcon> icons, int numFrames, int delay,
int repeat) {
this.numFrames = numFrames;
this.delay = delay;
this.repeat = repeat;
this.icons = icons;
this.frame = 0;
this.lastFrame = -1;
this.tick = -1;
}
@Override
public void draw(AbstractButton button, int frameNo) {
if (frameNo != lastFrame) {
// we do one clock tick when the incoming frame number changes
tick++;
}
lastFrame = frameNo;
if (frameNo == 0)
tick = 0;
if (repeat == -1 || tick < repeat) { // only update if we're still playing
frame = (tick / delay) % numFrames; // switch frames every delay
// ticks
System.out.println("tick=" + tick + ", repeat=" + repeat + "frame to show: " + frame);
}
Icon icon = icons.get(frame);
if (button.getIcon() != icon) {
button.setHorizontalAlignment(SwingConstants.LEFT);
button.setVerticalAlignment(SwingConstants.BOTTOM);
button.setIcon(icon);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + delay;
result = prime * result + ((icons == null) ? 0 : icons.hashCode());
result = prime * result + numFrames;
result = prime * result + repeat;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AnimatedImage other = (AnimatedImage) obj;