/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package continuity;
import continuity.View.NodeView;
import continuity.View.RoomView;
import java.util.ArrayList;
import java.util.List;
/**
* Az egy helyiségben lévő mezőket tárolja.
* A többi helyiséggel való kompatibilitás nyilvántartása is a feladata.
* Ha üres a szoba, akkor a nincsenek határmezői.
* @author FornetTeam
*/
public class Room {
/**
* A helyiségben lévő mezők.
*/
private List<Node> nodes;
/**
* A szoba különböző oldalain elhelyezkedő mezők felsorolása.
* Egy oldalhoz tartozik egy List<Node>. Indexelésük a Direction osztáy
* toInt fgvényenek megfelelően történik (0 - Jobb, 1 - Le, 2 - Bal, 3 - Fel).
* A bal és jobb oldali listában fentről lefele vannak benne az mezők, míg
* alul és felül balról jobbra.
* Üres Room esetén az összes borderNode null értékű, viszont a szoba
* nagyságának megfelelő null benne van a listákban.
* (Ezt a Map swapjénél fogjuk kihasználni).
*/
private List<List<Node>> borderNodes;
/**
* A helyiség, mely más helyiséggel illeszkedik a különböző irányokból.
* Az egyes listák egy adott irányból vett kompatibilitást (illeszkedést)
* reprezentálnak. Az egyes listák indexelése az Direction osztály toInt
* fgvényének megfelelően fog történni,
* azaz (0 - Jobb, 1 1 - Le, 2 - Bal, 3 - Fel).
*/
private List<List<Room>> compatible;
/**
* Az adott helyiség szomszédait tárolja
* (0 - Jobb, 1 1 - Le, 2 - Bal, 3 - Fel).
*/
private List<Room> neighbors;
/**
* A konstruktor a leírásnak (description paraméter) megfelelő szobát hoz létre.
* @param game A Node-ok létrehozásakor átadandó Communication példány.
* @param characters A játék karaktereinek listája.
* @param d A pályán lévő ajtó.
* @param description
*/
public Room(Communication game, ArrayList<Character> characters, ArrayList<String> description, DoorElement d) {
neighbors=new ArrayList<Room>();
nodes=new ArrayList<Node>();
compatible=new ArrayList<List<Room>>();
borderNodes=new ArrayList<List<Node>>();
//kompatibilitási listák létrehozása
//benne van, hogy 4 oldala van a szobának!
for(int i=0;i<4;i++) {
compatible.add(new ArrayList<Room>());
borderNodes.add(new ArrayList<Node>());
neighbors.add(null);
}
//első sor kezelése
String[] s=description.get(0).split(" ");
//ha üres szoba
if(s[0].equals("EmptyRoom")) {
int height=Integer.parseInt(s[1]);
int width=Integer.parseInt(s[2]);
for(int i=0;i<height;i++) {
borderNodes.get(Direction.Left.toInt()).add(null);
borderNodes.get(Direction.Right.toInt()).add(null);
}
for(int i=0;i<width;i++) {
borderNodes.get(Direction.Up.toInt()).add(null);
borderNodes.get(Direction.Down.toInt()).add(null);
}
}
else {
//nem üres szoba-->leírás alapján létrehozzuk
int width=s.length;
int height=description.size();
for(int i=0;i<description.size();i++) {
s=description.get(i).split(" ");
for(int j=0;j<s.length;j++) {
Node n=new Node();
nodes.add(n);
char c=s[j].charAt(0);
switch(c) {
case 'E':
n.setElement(new EmptyElement(game));
break;
case 'K':
KeyElement k =new KeyElement(game);
k.setDoor(d);
n.setElement(k);
break;
case 'D':
n.setElement(d);
break;
case 'O':
n.setElement(new ObstacleElement(game));
break;
default:
// mi legyen ha érvénytelen a bemenet
break;
}
c=s[j].charAt(1);
switch(c) {
case '1':
n.setIsHere(0, true);
characters.get(0).setPosition(n);
break;
case '2':
n.setIsHere(1, true);
characters.get(1).setPosition(n);
break;
case '3':
n.setIsHere(0, true);
characters.get(0).setPosition(n);
n.setIsHere(1, true);
characters.get(1).setPosition(n);
break;
}
}
}
//Node-ok szomszédainak beállítása és a borderNodes listák feltöltése
for(int i=0;i<nodes.size();i++) {
Node n=nodes.get(i);
//alsó sor indexei
if(i>=width*(height-1)) {
borderNodes.get(Direction.Down.toInt()).add(n);
}
else
{
//alsó szomszéd állítás
n.setNeighbor(nodes.get(i+width), Direction.Down.toInt());
}
//felső sor indexei
if(i<width) {
borderNodes.get(Direction.Up.toInt()).add(n);
}
else
{
//felső szomszéd beállítás
n.setNeighbor(nodes.get(i-width), Direction.Up.toInt());
}
//bal oldal indexei
if(i%width==0) {
borderNodes.get(Direction.Left.toInt()).add(n);
}
else {
//bal szomszéd beállítása
n.setNeighbor(nodes.get(i-1), Direction.Left.toInt());
}
//jobb oldal indexei
if(i%width==width-1) {
borderNodes.get(Direction.Right.toInt()).add(n);
}
else {
//jobb szomszéd beállítása
n.setNeighbor(nodes.get(i+1), Direction.Right.toInt());
}
}
//Kész a megfelelő szoba.
}
}
/**
* Egy szomszédos szoba beállítása,
* valamint a megfelelő oldalakon lévő mezők összekötése.
* Ha a két szoba kompatibilis, akkor A nem null, a position oldalon lévő
* border Node-oknak beállítjuk szomszédnak a paraméterként kapott room
* ellentétes oldalén lévő borderNode-okat. (a Node-ok setNeighbor
* függvényének hívogatásáva) Ha nem kompatibilis, akkor meghívjuk a
* changeNeighbor függvényt ugyanezekkel a paraméterekkel.
* @param room Az új szomszédszoba.
* @param dir Az irány, ahova a szoba szomszédnak kerül.
*/
public void setNeighbor(Room room, Direction dir) {
//megnézzük, hogy kompatibilis-e
if(compatible.get(dir.toInt()).contains(room)) {
//ha igen
for(int i=0;i<borderNodes.get(dir.toInt()).size();i++) {
borderNodes.get(dir.toInt()).get(i).setNeighbor(
room.getBorderNode(dir.getOpposite(), i), dir.toInt());
}
neighbors.set(dir.toInt(), room);
}
else {
//ha nem
changeNeighbor(room, dir);
}
}
/**
* Az megfelelő oldalon lévő szomszéd lekérdezése (dir.toInt()).
* @param dir Az irány.
* @return A szomszéd szoba.
*/
public Room getNeighbor(Direction dir) {
return neighbors.get(dir.toInt());
}
/**
* Egy adott oldal, nbr-edik mezőjét adja vissza.
* @param dir Az irány.
* @param nbr Sorszám.
* @return A megfelelő oldalon és helyen lévő borderNode.
*/
public Node getBorderNode(Direction dir, int nbr) {
return borderNodes.get(dir.toInt()).get(nbr);
}
/**
* A neighbor dir-nek megfelelő elemének(dir.toInt()) a paraméterként
* kapott room-ot állítja be. Emellett az adott oldalon lévő mezőknek
* null-t állít be szomszédainak.
* @param room Az új szomszéd szoba.
* @param dir Az irány.
*/
public void changeNeighbor(Room room, Direction dir){
//ha emptyRoom a this
if(getBorderNode(Direction.Up, 0)==null &&
getBorderNode(Direction.Down, 0)==null &&
getBorderNode(Direction.Right, 0)==null &&
getBorderNode(Direction.Left, 0)==null) {
neighbors.set(dir.toInt(), room);
return;
}
for(int i=0;i<borderNodes.get(dir.toInt()).size();i++) {
borderNodes.get(dir.toInt()).get(i).setNeighbor(null, dir.toInt());
}
neighbors.set(dir.toInt(), room);
}
/**
* A megfelelő oldali kompatibilitási listához a room hozzáadása.
* @param r A kompatibilis Romm
* @param dir Az irány.
*/
public void addCompatible(Room r, Direction dir){
compatible.get(dir.toInt()).add(r);
}
@Override
public String toString() {
String eol=System.getProperty("line.separator");
String ret = "";
//Ha üres a szoba
if(borderNodes.get(Direction.Right.toInt()).get(0)==null &&
borderNodes.get(Direction.Down.toInt()).get(0)==null &&
borderNodes.get(Direction.Left.toInt()).get(0)==null &&
borderNodes.get(Direction.Up.toInt()).get(0)==null) {
return "EmptyRoom" + eol;
}
int width=borderNodes.get(Direction.Up.toInt()).size();
int height=borderNodes.get(Direction.Right.toInt()).size();
for(int i=0;i<height;i++) {
for(int j=0;j<width;j++) {
ret+=nodes.get(i*width+j).toString()+ " ";
}
ret+=eol;
}
return ret;
}
public RoomView createRoomView() {
int width=borderNodes.get(Direction.Up.toInt()).size();
int height=borderNodes.get(Direction.Left.toInt()).size();
NodeView[][] nodeViews=new NodeView[height][width];
//ha emptyRoom a this
if(getBorderNode(Direction.Up, 0)==null &&
getBorderNode(Direction.Down, 0)==null &&
getBorderNode(Direction.Right, 0)==null &&
getBorderNode(Direction.Left, 0)==null) {
NodeView[][] emptyNodes = new NodeView[borderNodes.get(Direction.Left.toInt()).size()][];
for (int i = 0; i < emptyNodes.length; i++) {
emptyNodes[i] = new NodeView[borderNodes.get(Direction.Up.toInt()).size()];
}
return new RoomView(emptyNodes);
}
for(int i=0; i< height;i++) {
for(int j=0;j<width;j++) {
nodeViews[i][j]=nodes.get(i*width+j).createNodeView();
}
}
return new RoomView(nodeViews);
}
}