<commit_before>package com.planet_ink.coffee_mud.Locales;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.GridZones.XYVector;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.Basic.GenCage;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;

import com.planet_ink.coffee_mud.Libraries.interfaces.*;

/*
   Copyright 2002-2019 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

public class StdGrid extends StdRoom implements GridLocale
{
	@Override
	public String ID()
	{
		return "StdGrid";
	}

	protected Room[][] 		  subMap=null;
	protected String[] 		  descriptions=new String[0];
	protected String[] 		  displayTexts=new String[0];
	protected List<CrossExit> gridexits=new SVector<CrossExit>();
	protected int xsize=5;
	protected int ysize=5;

	public StdGrid()
	{
		super();
		myID=getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
	}

	@Override
	protected void cloneFix(final Room E)
	{
		super.cloneFix(E);
		if(E instanceof StdGrid)
		{
			descriptions=((StdGrid)E).descriptions.clone();
			displayTexts=((StdGrid)E).displayTexts.clone();
			gridexits=new SVector<CrossExit>(((StdGrid)E).gridexits);
		}
	}

	@Override
	public String getGridChildLocaleID()
	{
		return "StdRoom";
	}

	@Override
	public Room getGridChild(final XYVector xy)
	{
		if(xy==null)
			return null;
		return this.getGridChild(xy.x,xy.y);
	}

	@Override
	public CMObject newInstance()
	{
		if(CMSecurity.isDisabled(CMSecurity.DisFlag.FATGRIDS))
		{
			String name=ID();
			if(!name.endsWith("Grid"))
				return super.newInstance();
			name=name.substring(0,name.length()-4)+"ThinGrid";
			final Room R=CMClass.getLocale(name);
			if(R==null)
				return super.newInstance();
			if(R instanceof StdGrid)
				return super.newInstance();
			return R.newInstance();
		}
		return super.newInstance();
	}

	@Override
	public void destroy()
	{
		super.destroy();
		if(subMap!=null)
		{
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
				{
					if(element[y]!=null)
						element[y].destroy();
				}
			}
		}
		subMap=null;
		descriptions=null;
		displayTexts=null;
		gridexits=null;
	}

	@Override
	public int xGridSize()
	{
		return xsize;
	}

	@Override
	public int yGridSize()
	{
		return ysize;
	}

	@Override
	public void setXGridSize(final int x)
	{
		if (x > 0)
			xsize = x;
	}

	@Override
	public void setYGridSize(final int y)
	{
		if (y > 0)
			ysize = y;
	}

	@Override
	public XYVector getRoomXY(final String roomID)
	{
		final Room room=CMLib.map().getRoom(roomID);
		if(room==null)
			return null;
		return getRoomXY(room);
	}

	@Override
	public XYVector getRoomXY(final Room room)
	{
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			for(int x=0;x<subMap.length;x++)
			{
				for(int y=0;y<subMap[x].length;y++)
				{
					if(subMap[x][y]==room)
						return new XYVector(x,y);
				}
			}
		}
		return null;
	}

	@Override
	public Room prepareRoomInDir(final Room fromRoom, final int direction)
	{
		if(amDestroyed)
		{
			final Room R=CMLib.map().getRoom(roomID());
			if(R!=null)
				return R.prepareRoomInDir(fromRoom,direction);
			return super.prepareRoomInDir(fromRoom,direction);
		}
		return getAltRoomFrom(fromRoom,direction);
	}

	@Override
	public Room prepareGridLocale(final Room fromRoom, final Room toRoom, final int direction)
	{
		return toRoom;
	}

	@Override
	public void setDescription(String newDescription)
	{
		super.setDescription(newDescription);
		final Vector<String> descriptions=new Vector<String>();
		int x=newDescription.toUpperCase().indexOf("<P>");
		while(x>=0)
		{
			final String s=newDescription.substring(0,x).trim();
			if(s.length()>0)
				descriptions.addElement(s);
			newDescription=newDescription.substring(x+3).trim();
			x=newDescription.toUpperCase().indexOf("<P>");
		}
		if(newDescription.length()>0)
			descriptions.addElement(newDescription);
		this.descriptions=descriptions.toArray(new String[0]);
	}

	@Override
	public void setDisplayText(String newDisplayText)
	{
		super.setDisplayText(newDisplayText);
		final Vector<String> displayTexts=new Vector<String>();
		int x=newDisplayText.toUpperCase().indexOf("<P>");
		while(x>=0)
		{
			final String s=newDisplayText.substring(0,x).trim();
			if(s.length()>0)
				displayTexts.addElement(s);
			newDisplayText=newDisplayText.substring(x+3).trim();
			x=newDisplayText.toUpperCase().indexOf("<P>");
		}
		if(newDisplayText.length()>0)
			displayTexts.addElement(newDisplayText);
		this.displayTexts=displayTexts.toArray(new String[0]);
	}

	@Override
	public Iterator<CrossExit> outerExits()
	{
		return gridexits.iterator();
	}

	@Override
	public void addOuterExit(final CrossExit x)
	{
		if(x!=null)
			gridexits.add(x);
	}

	@Override
	public void delOuterExit(final CrossExit x)
	{
		gridexits.remove(x);
	}

	public Room getAltRoomFrom(Room loc, final int direction)
	{
		if((loc==null)||(direction<0))
			return null;
		final int opDirection=Directions.getOpDirectionCode(direction);

		getBuiltGrid();
		Room[][] grid=null;
		final List<CrossExit> gridexits=this.gridexits;
		if((gridexits!=null)&&(gridexits.size()>0))
		{
			grid=getBuiltGrid();
			final String roomID=CMLib.map().getExtendedRoomID(loc);
			if(grid!=null)
			{
				for(int d=0;d<gridexits.size();d++)
				{
					final CrossExit EX=gridexits.get(d);
					if((!EX.out)
					&&(EX.destRoomID.equalsIgnoreCase(roomID))
					&&(EX.dir==direction)
					&&(EX.x>=0)&&(EX.y>=0)&&(EX.x<xGridSize())&&(EX.y<yGridSize())
					&&(grid[EX.x][EX.y]!=null))
						return grid[EX.x][EX.y];
				}
			}
		}

		final Room oldLoc=loc;
		if(loc.getGridParent()!=null)
			loc=loc.getGridParent();
		if((oldLoc!=loc)&&(loc instanceof GridLocale))
		{
			if(grid==null)
				grid=getBuiltGrid();
			if(grid!=null)
			{
				final XYVector xy=((GridLocale)loc).getRoomXY(oldLoc);
				if((xy!=null)&&(xy.x>=0)&&(xy.y>=0))
				{
					switch(opDirection)
					{
					case Directions.EAST:
						if((((GridLocale)loc).yGridSize()==yGridSize()))
							return grid[grid.length-1][xy.y];
						break;
					case Directions.WEST:
						if((((GridLocale)loc).yGridSize()==yGridSize()))
							return grid[0][xy.y];
						break;
					case Directions.NORTHWEST:
						return grid[0][0];
					case Directions.NORTHEAST:
						return grid[grid.length-1][0];
					case Directions.NORTH:
						if((((GridLocale)loc).xGridSize()==xGridSize()))
							return grid[xy.x][0];
						break;
					case Directions.SOUTH:
						if((((GridLocale)loc).xGridSize()==xGridSize()))
							return grid[xy.x][grid[0].length-1];
						break;
					case Directions.SOUTHEAST:
						return grid[grid.length-1][grid[0].length-1];
					case Directions.SOUTHWEST:
						return grid[0][grid[0].length-1];
					}
				}
			}
		}
		return findCenterRoom(opDirection);
	}

	protected Room[][] getBuiltGrid()
	{
		if(subMap==null)
			buildGrid();
		if(subMap!=null)
			return subMap.clone();
		return null;
	}

	@Override
	public Room getRandomGridChild()
	{
		final List<Room> V=getAllRooms();
		if(V.size()==0)
			return null;
		return V.get(CMLib.dice().roll(1,V.size(),-1));
	}

	@Override
	public List<Room> getAllRooms()
	{
		final Vector<Room> V=new Vector<Room>();
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
					V.addElement(element[y]);
			}
		}
		return V;
	}

	@Override
	public List<Room> getAllRoomsFilled()
	{
		final Vector<Room> V=new Vector<Room>();
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
				{
					final Room R=element[y];
					if(R==null)
					{
						V.clear();
						if(!this.amDestroyed())
							return getAllRoomsFilled();
						return V;
					}
					if(!V.contains(R))
						V.addElement(R);
					final List<Room> sky = R.getSky();
					if(sky == null)
						Log.errOut("No Sky for "+R.roomID());
					else
					{
						for(final Room R2 : sky)
						{
							if(R2 instanceof GridLocale)
								V.addAll(((GridLocale)R2).getAllRoomsFilled());
							else
							if(!V.contains(R2))
								V.add(R2);
						}
					}
				}
			}
		}
		return V;
	}

	private static final Iterator<Room> emptyIterator = new Iterator<Room>()
	{
		@Override
		public boolean hasNext()
		{
			return false;
		}

		@Override
		public Room next()
		{
			throw new NoSuchElementException();
		}<commit_msg>Grid fill optimizer, although im starting to like the idea of a custom enumerator better.<commit_after>package com.planet_ink.coffee_mud.Locales;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.GridZones.XYVector;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.Basic.GenCage;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;

import com.planet_ink.coffee_mud.Libraries.interfaces.*;

/*
   Copyright 2002-2019 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

public class StdGrid extends StdRoom implements GridLocale
{
	@Override
	public String ID()
	{
		return "StdGrid";
	}

	protected Room[][] 		  subMap=null;
	protected String[] 		  descriptions=new String[0];
	protected String[] 		  displayTexts=new String[0];
	protected List<CrossExit> gridexits=new SVector<CrossExit>();
	protected int xsize=5;
	protected int ysize=5;

	public StdGrid()
	{
		super();
		myID=getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
	}

	@Override
	protected void cloneFix(final Room E)
	{
		super.cloneFix(E);
		if(E instanceof StdGrid)
		{
			descriptions=((StdGrid)E).descriptions.clone();
			displayTexts=((StdGrid)E).displayTexts.clone();
			gridexits=new SVector<CrossExit>(((StdGrid)E).gridexits);
		}
	}

	@Override
	public String getGridChildLocaleID()
	{
		return "StdRoom";
	}

	@Override
	public Room getGridChild(final XYVector xy)
	{
		if(xy==null)
			return null;
		return this.getGridChild(xy.x,xy.y);
	}

	@Override
	public CMObject newInstance()
	{
		if(CMSecurity.isDisabled(CMSecurity.DisFlag.FATGRIDS))
		{
			String name=ID();
			if(!name.endsWith("Grid"))
				return super.newInstance();
			name=name.substring(0,name.length()-4)+"ThinGrid";
			final Room R=CMClass.getLocale(name);
			if(R==null)
				return super.newInstance();
			if(R instanceof StdGrid)
				return super.newInstance();
			return R.newInstance();
		}
		return super.newInstance();
	}

	@Override
	public void destroy()
	{
		super.destroy();
		if(subMap!=null)
		{
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
				{
					if(element[y]!=null)
						element[y].destroy();
				}
			}
		}
		subMap=null;
		descriptions=null;
		displayTexts=null;
		gridexits=null;
	}

	@Override
	public int xGridSize()
	{
		return xsize;
	}

	@Override
	public int yGridSize()
	{
		return ysize;
	}

	@Override
	public void setXGridSize(final int x)
	{
		if (x > 0)
			xsize = x;
	}

	@Override
	public void setYGridSize(final int y)
	{
		if (y > 0)
			ysize = y;
	}

	@Override
	public XYVector getRoomXY(final String roomID)
	{
		final Room room=CMLib.map().getRoom(roomID);
		if(room==null)
			return null;
		return getRoomXY(room);
	}

	@Override
	public XYVector getRoomXY(final Room room)
	{
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			for(int x=0;x<subMap.length;x++)
			{
				for(int y=0;y<subMap[x].length;y++)
				{
					if(subMap[x][y]==room)
						return new XYVector(x,y);
				}
			}
		}
		return null;
	}

	@Override
	public Room prepareRoomInDir(final Room fromRoom, final int direction)
	{
		if(amDestroyed)
		{
			final Room R=CMLib.map().getRoom(roomID());
			if(R!=null)
				return R.prepareRoomInDir(fromRoom,direction);
			return super.prepareRoomInDir(fromRoom,direction);
		}
		return getAltRoomFrom(fromRoom,direction);
	}

	@Override
	public Room prepareGridLocale(final Room fromRoom, final Room toRoom, final int direction)
	{
		return toRoom;
	}

	@Override
	public void setDescription(String newDescription)
	{
		super.setDescription(newDescription);
		final Vector<String> descriptions=new Vector<String>();
		int x=newDescription.toUpperCase().indexOf("<P>");
		while(x>=0)
		{
			final String s=newDescription.substring(0,x).trim();
			if(s.length()>0)
				descriptions.addElement(s);
			newDescription=newDescription.substring(x+3).trim();
			x=newDescription.toUpperCase().indexOf("<P>");
		}
		if(newDescription.length()>0)
			descriptions.addElement(newDescription);
		this.descriptions=descriptions.toArray(new String[0]);
	}

	@Override
	public void setDisplayText(String newDisplayText)
	{
		super.setDisplayText(newDisplayText);
		final Vector<String> displayTexts=new Vector<String>();
		int x=newDisplayText.toUpperCase().indexOf("<P>");
		while(x>=0)
		{
			final String s=newDisplayText.substring(0,x).trim();
			if(s.length()>0)
				displayTexts.addElement(s);
			newDisplayText=newDisplayText.substring(x+3).trim();
			x=newDisplayText.toUpperCase().indexOf("<P>");
		}
		if(newDisplayText.length()>0)
			displayTexts.addElement(newDisplayText);
		this.displayTexts=displayTexts.toArray(new String[0]);
	}

	@Override
	public Iterator<CrossExit> outerExits()
	{
		return gridexits.iterator();
	}

	@Override
	public void addOuterExit(final CrossExit x)
	{
		if(x!=null)
			gridexits.add(x);
	}

	@Override
	public void delOuterExit(final CrossExit x)
	{
		gridexits.remove(x);
	}

	public Room getAltRoomFrom(Room loc, final int direction)
	{
		if((loc==null)||(direction<0))
			return null;
		final int opDirection=Directions.getOpDirectionCode(direction);

		getBuiltGrid();
		Room[][] grid=null;
		final List<CrossExit> gridexits=this.gridexits;
		if((gridexits!=null)&&(gridexits.size()>0))
		{
			grid=getBuiltGrid();
			final String roomID=CMLib.map().getExtendedRoomID(loc);
			if(grid!=null)
			{
				for(int d=0;d<gridexits.size();d++)
				{
					final CrossExit EX=gridexits.get(d);
					if((!EX.out)
					&&(EX.destRoomID.equalsIgnoreCase(roomID))
					&&(EX.dir==direction)
					&&(EX.x>=0)&&(EX.y>=0)&&(EX.x<xGridSize())&&(EX.y<yGridSize())
					&&(grid[EX.x][EX.y]!=null))
						return grid[EX.x][EX.y];
				}
			}
		}

		final Room oldLoc=loc;
		if(loc.getGridParent()!=null)
			loc=loc.getGridParent();
		if((oldLoc!=loc)&&(loc instanceof GridLocale))
		{
			if(grid==null)
				grid=getBuiltGrid();
			if(grid!=null)
			{
				final XYVector xy=((GridLocale)loc).getRoomXY(oldLoc);
				if((xy!=null)&&(xy.x>=0)&&(xy.y>=0))
				{
					switch(opDirection)
					{
					case Directions.EAST:
						if((((GridLocale)loc).yGridSize()==yGridSize()))
							return grid[grid.length-1][xy.y];
						break;
					case Directions.WEST:
						if((((GridLocale)loc).yGridSize()==yGridSize()))
							return grid[0][xy.y];
						break;
					case Directions.NORTHWEST:
						return grid[0][0];
					case Directions.NORTHEAST:
						return grid[grid.length-1][0];
					case Directions.NORTH:
						if((((GridLocale)loc).xGridSize()==xGridSize()))
							return grid[xy.x][0];
						break;
					case Directions.SOUTH:
						if((((GridLocale)loc).xGridSize()==xGridSize()))
							return grid[xy.x][grid[0].length-1];
						break;
					case Directions.SOUTHEAST:
						return grid[grid.length-1][grid[0].length-1];
					case Directions.SOUTHWEST:
						return grid[0][grid[0].length-1];
					}
				}
			}
		}
		return findCenterRoom(opDirection);
	}

	protected Room[][] getBuiltGrid()
	{
		if(subMap==null)
			buildGrid();
		if(subMap!=null)
			return subMap.clone();
		return null;
	}

	@Override
	public Room getRandomGridChild()
	{
		final List<Room> V=getAllRooms();
		if(V.size()==0)
			return null;
		return V.get(CMLib.dice().roll(1,V.size(),-1));
	}

	@Override
	public List<Room> getAllRooms()
	{
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			final Vector<Room> roomsV=new Vector<Room>(subMap.length * ((subMap.length>0)?subMap[0].length:0));
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
				{
					final Room R=element[y];
					if(R!=null)
						roomsV.addElement(R);
				}
			}
			return roomsV;
		}
		return new Vector<Room>(0);
	}

	@Override
	public List<Room> getAllRoomsFilled()
	{
		final Room[][] subMap=getBuiltGrid();
		if(subMap!=null)
		{
			final Vector<Room> roomsV=new Vector<Room>(subMap.length * ((subMap.length>0)?subMap[0].length:0));
			for (final Room[] element : subMap)
			{
				for(int y=0;y<element.length;y++)
				{
					final Room R=element[y];
					if(R==null)
					{
						roomsV.clear();
						if(!this.amDestroyed())
						{
							CMLib.s_sleep(10);
							for (final Room[] element2 : getBuiltGrid())
							{
								for(int y2=0;y2<element2.length;y2++)
								{
									final Room R2=element[y2];
									if(R2==null)
										return this.getAllRooms(); // give up.
								}
							}
							return getAllRoomsFilled();
						}
						return roomsV;
					}
					if(!roomsV.contains(R))
						roomsV.addElement(R);
					final List<Room> sky = R.getSky();
					if(sky == null)
						Log.errOut("No Sky for "+R.roomID());
					else
					{
						for(final Room R2 : sky)
						{
							if(R2 instanceof GridLocale)
								roomsV.addAll(((GridLocale)R2).getAllRoomsFilled());
							else
							if(!roomsV.contains(R2))
								roomsV.add(R2);
						}
					}
				}
			}
		}
		return new Vector<Room>(0);
	}

	private static final Iterator<Room> emptyIterator = new Iterator<Room>()
	{
		@Override
		public boolean hasNext()
		{
			return false;
		}

		@Override
		public Room next()
		{
			throw new NoSuchElementException();
		}
{'fraction_non_alphanumeric': 0.14908834491790068, 'fraction_numerical': 0.007806991034552231, 'mean_word_length': 3.7682516810758884, 'pattern_counts': {'":': 0, '<': 72, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4930774', 'n_tokens_mistral': 8620, 'n_tokens_neox': 7186, 'n_words': 1276}