I'm trying to achieve a method that I can call to create multiple items
This is the method I'm trying to get it to work
public void AddMultipleItems(string[] itemKey, int[] amount)
{
for (int i = 0; i < itemKey.Length; i++)
{
Item item;
item = ItemCollection[itemKey[i]];
for (int x = 0; x < amount.Length; x++)
{
if (inventory.CanAddItem(item, amount[x]) == true)
{
inventory.AddItem(item.GetCopy());
}
else if (inventory.CanAddItem(item, amount[x]) == false)
{
Debug.Log("Inventory Full");
break;
}
}
}
}
And then this method will be called to add in items like this:
itemDB.AddMultipleItems(new string[] { "Boots", "Gold Coin", "Apple" }, new int[] {1, 2, 3 });
Result: I get 3 Boots, 3 Gold coin and 3 Apple. when I should be getting 1 Boots, 2 Gold Coin & 3 Apples,
I've done a similar Method like this except it doesn't require array parameters and it works perfectly:
public void AddItems(string itemKey, int amount)
{
//First check if entered itemKey parameter exists in ItemCollection Dictionary
if (ItemCollection.ContainsKey(itemKey))
{
Item item;
item = ItemCollection[itemKey];
if (item != null)
{
//check if we can add the item and the amount of it
if (inventory.CanAddItem(item, amount))
{
//loop through the total amount
for (int i = 0; i < amount; i++)
{
//add the item
inventory.AddItem(item.GetCopy());
}
Debug.Log(itemKey + " Added Successfully!");
}
else
{
Debug.Log("Not enough space in Inventory");
}
}
else
{
Debug.Log("Null Item");
}
}
else
{
Debug.Log(itemKey + " does not exist in ItemDatabase's Dictionary");
}
}
So basically another way of looking at it is how can I turn the AddItems(string itemKey, int amount) into AddItems(string[] itemKey, int[] amount). its the for loop, foreach loop and arrays that are kinda tripping me over since I'm not very good at those.
Appreciate any help, Thank you!
For every item you are iterating over the entire amount array which has 3 entries. I would actually expect that for each item you get 1+2+3 = 6 items added.
Wouldn't you rather want to only get the amount to add from the one entry in amount with the same index as the given itemKey: amount[i]
public void AddMultipleItems(string[] itemKey, int[] amount)
{
for (int i = 0; i < itemKey.Length; i++)
{
Item item;
item = ItemCollection[itemKey[i]];
if (inventory.CanAddItem(item, amount[i]))
{
inventory.AddItem(item.GetCopy());
}
else // your if condition here was redundant
{
Debug.Log("Inventory Full");
}
}
}
In general you already have a method for adding a single item so I wouldn't re-implement that for multiple ones but rather call it from the loop like
public void AddMultipleItems(string[] itemKey, int[] amount)
{
for (int i = 0; i < itemKey.Length; i++)
{
// Instead of re-implement rather call your existing method
// and treat each value pair as if ti was a single add call
AddItems(itemKey[i], amount[i]);
}
}
Then passing in two separate arrays is pretty error prone and hard to maintain. I would probably rather pass in a Dictionary<string, int> like e.g.
public void AddMultipleItems(Dictionary<string, int> itemsToAdd)
{
foreach (var kvp in itemsToAdd)
{
AddItems(kvp.Key, kvp.Value);
}
}
and then call it like
itemDB.AddMultipleItems(new Dictionary<string, int>{ {"Boots", 1}, {"Gold Coin", 2}, {"Apple", 3}});
Related
I have a gameObject with an ID, the gameObjects are spawned by giving initial ID: 1 , then any after spawned will be +1 so next is ID: 2.
I have two buttons that check current gameObjects ID#, BackOneButton (-1) and PlusOneButton (+1).
Currently it works but only if the array of gameObjects have IDs in order like for example [gameObject-ID:1], [gameObject-ID:2], [gameObject-ID:3]
But since you can self destruct a certain gameObject, here is where the error is --->
Now the array is not in order for example [gameObject-ID:1], [gameObject-ID:3], [gameObject-ID:4]. So if I'm currently in [gameObject-ID:3] and I use the BackOneButton and looks for ID: 2 it won't find it BUT there is ID:1. That's my error, I can't seem to figure out how to handle this.
Basically, How do I handle missing increments and skip over the missing?
Left Button (MinusOneButton)
void ButtonAction_LeftMinusOne()
{
// Get list of all gameObjects and -1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
case "1":
// nothing to go back to, this is ID: 1
break;
default:
// currently in (ID: 2 & Up) second object
int currentID = int.Parse(idObjNumber);
string idBackOne = (currentID - 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idBackOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
Right Button (PlusOneButton)
void ButtonAction_RightPlusOne()
{
// Get list of all objects and +1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
default:
// currently in (ID: 1 & Up) object
int currentID = int.Parse(idObjNumber);
string idPlusOne = (currentID + 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idPlusOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
It would be way better (especially regarding maintenance) and more efficient to have a central manager class with a List<GameObject> where you simply Add and Remove items dynamically. (Since you already seem to have one in manager I would rather extend that one)
public static class ObjectsManager
{
// If you are not concerned about
// capsulation you could ofcourse make this public as well
// but I thought this is cleaner
private static List<GameObject> objects;
// Read-only property
public static int Count
{
get
{
Initialize();
return objects.Count;
}
}
// initialize the list once
// I first had this in e.g. Awake
// but now you can easily use this in multiple scenes
public static void Initialize(bool force reinitialize = false)
{
if(objects != null && ! reinitialize) return;
objects = FindObjectsWithTag("Object").ToList();
}
public static void Add(GameObject newObject)
{
Initialize();
if(objects.Contains(newObject) return;
objects.Add(newObject);
}
public static void Destroy(GameObject toDestroy)
{
Initialize();
if(objects.Contains(toDestroy)
{
objects.Remove(toDestroy);
}
Object.Destroy(toDestroy);
}
public static int IndexOf(GameObject obj)
{
Initialize();
return objects.IndexOf(obj);
}
public static GameObject GetByIndex(int index)
{
Initialize();
// Use modulo to wrap around the index in case
// +1 or -1 exceeds the list ends
// in your case you might not need it
// but I decided to add it to be more flexible
var nextIndex = (index + 1) % objects.Count;
return objects[index];
}
}
Everytime you Instantiate a new object make sure to also call
ObjectsManager.Add(newObject);
and everytime where you destroy an object rather use
ObjectsManager.Destroy(objectToDestroy);
so it is also removed from the list first.
Then you can easily use
var currentIndex = ObjectsManager.IndexOf(certainObject);
to get the current index of an object and simply move through the index (+1, -1)
var nextObject = ObjectsManager.GetByIndex(currentIndex + 1);
var lastObject = Objects manager.GetByIndex(currentIndex - 1);
In case you switch the scene you have reinitialize the list once in order to get rid of null references
ObjectsManager.Initialize(true);
In your example code you would e.g. use something like
void ButtonAction_LeftMinusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == 0)
{
// nothing to do go back to
// Except you want wrap around then simply remove this check
Debug.Log("Already is first object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex - 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}
And accordingly
void ButtonAction_RightPlusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == ObjectsManager.Count - 1)
{
// nothing to do go forward to
// Except you want wrap around then simply remove this check
Debug.Log("Already is last object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex + 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}
Hello :) I'm converting now Inventory system but i'm stuck on List / Arrays (JS).
Here's my script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[AddComponentMenu ("Inventory/Character Sheet")]
[RequireComponent(typeof (Inventory))]
public class Character : MonoBehaviour {
//The Character window (CSheet).
public Transform WeaponSlot; //This is where the Weapons are going to go (be parented too). In my case it's the "Melee" gameobject.
//private Item[] ArmorSlot;
private List<Item> ArmorSlot; //This is the built in Array that stores the Items equipped. You can change this to static if you want to access it from another script.
//public string[] ArmorSlotName;
public List<string> ArmorSlotName; //This determines how many slots the character has (Head, Legs, Weapon and so on) and the text on each slot.
//public Rect[] buttonPositions;
public List<Rect> buttonPositions; //This list will contain where all buttons, equipped or not will be and SHOULD HAVE THE SAME NUMBER OF cells as the ArmorSlot array.
Vector2 windowSize = new Vector2(375,300); //The size of the character window.
public bool useCustomPosition = false; //Do we want to use the customPosition variable to define where on the screen the Character window will appear.
Vector2 customPosition = new Vector2 (70, 70); //The custom position of the Character window.
public GUISkin cSheetSkin; //This is where you can add a custom GUI skin or use the one included (CSheetSkin) under the Resources folder.
public bool canBeDragged = true; //Can the Character window be dragged?
public KeyCode onOffButton = KeyCode.I; //The key to toggle the Character window on and of.
bool DebugMode = false; //If this is enabled, debug.logs will print out information when something happens (equipping items etc.).
static bool csheet = false; //Helps with turning the CharacterSheet on and off.
private Rect windowRect = new Rect(100,100,200,300); //Keeping track of our character window.
//These are keeping track of components such as equipmentEffects and Audio.
private Inventory playersinv; //Refers to the Inventory script.
private bool equipmentEffectIs = false;
private InvAudio invAudio;
private bool invDispKeyIsSame = false;
//Assign the differnet components to variables and other "behind the scenes" stuff.
void Awake ()
{
playersinv = GetComponent<Inventory>();
if (useCustomPosition == false)
{
windowRect = new Rect(Screen.width-windowSize.x-70,Screen.height-windowSize.y-(162.5f+70*2),windowSize.x,windowSize.y);
}
else
{
windowRect = new Rect(customPosition.x,customPosition.y,windowSize.x,windowSize.y);
}
invAudio = GetComponent<InvAudio>();
if (GetComponent<InventoryDisplay>().onOffButton == onOffButton)
{
invDispKeyIsSame = true;
}
}
//Take care of the array lengths.
void Start ()
{
ArmorSlot = new Item[ArmorSlotName.Count];
if (buttonPositions.Count != ArmorSlotName.Count)
{
Debug.LogError("The variables on the Character script attached to " + transform.name + " are not set up correctly. There needs to be an equal amount of slots on 'ArmorSlotName' and 'buttonPositions'.");
}
}
//Checking if we already have somthing equipped
bool CheckSlot(int tocheck)
{
bool toreturn = false;
if(ArmorSlot[tocheck]!=null){
toreturn=true;
}
return toreturn;
}
//Using the item. If we assign a slot, we already know where to equip it.
public void UseItem(Item i, int slot, bool autoequip)
{
if(i.isEquipment){
//This is in case we dbl click the item, it will auto equip it. REMEMBER TO MAKE THE ITEM TYPE AND THE SLOT YOU WANT IT TO BE EQUIPPED TO HAVE THE SAME NAME.
if(autoequip)
{
int index = 0; //Keeping track of where we are in the list.
int equipto = 0; //Keeping track of where we want to be.
foreach(string a in ArmorSlotName) //Loop through all the named slots on the armorslots list
{
if(a == i.itemType) //if the name is the same as the armor type.
{
equipto=index; //We aim for that slot.
}
index++; //We move on to the next slot.
}
EquipItem(i,equipto);
}
else //If we dont auto equip it then it means we must of tried to equip it to a slot so we make sure the item can be equipped to that slot.
{
if(i.itemType==ArmorSlotName[slot]) //If types match.
{
EquipItem(i,slot); //Equip the item to the slot.
}
}
}
if (DebugMode)
{
Debug.Log(i.name + " has been used");
}
}
//Equip an item to a slot.
void EquipItem(Item i, int slot)
{
if(i.itemType == ArmorSlotName[slot]) //If the item can be equipped there:
{
if(CheckSlot(slot)) //If theres an item equipped to that slot we unequip it first:
{
UnequipItem(ArmorSlot[slot]);
ArmorSlot[slot]=null;
}
ArmorSlot[slot]=i; //When we find the slot we set it to the item.
gameObject.SendMessage ("PlayEquipSound", SendMessageOptions.DontRequireReceiver); //Play sound
//We tell the Item to handle EquipmentEffects (if any).
if (i.GetComponent<EquipmentEffect>() != null)
{
equipmentEffectIs = true;
i.GetComponent<EquipmentEffect>().EquipmentEffectToggle(equipmentEffectIs);
}
//If the item is also a weapon we call the PlaceWeapon function.
if (i.isAlsoWeapon == true)
{
if (i.equippedWeaponVersion != null)
{
PlaceWeapon(i);
}
else
{
Debug.LogError("Remember to assign the equip weapon variable!");
}
}
if (DebugMode)
{
Debug.Log(i.name + " has been equipped");
}
playersinv.RemoveItem(i.transform); //We remove the item from the inventory
}
}
//Unequip an item.
void UnequipItem(Item i)
{
gameObject.SendMessage ("PlayPickUpSound", SendMessageOptions.DontRequireReceiver); //Play sound
//We tell the Item to disable EquipmentEffects (if any).
if (i.equipmentEffect != null)
{
equipmentEffectIs = false;
i.GetComponent<EquipmentEffect>().EquipmentEffectToggle(equipmentEffectIs);
}
//If it's a weapon we call the RemoveWeapon function.
if (i.itemType == "Weapon")
{
RemoveWeapon(i);
}
if (DebugMode)
{
Debug.Log(i.name + " has been unequipped");
}
playersinv.AddItem(i.transform);
}
//Places the weapon in the hand of the Player.
void PlaceWeapon (Item item)
{
GameObject Clone = GameObject.Instantiate(item.equippedWeaponVersion, WeaponSlot.position, WeaponSlot.rotation) as GameObject;
Clone.name = item.equippedWeaponVersion.name;
Clone.transform.parent = WeaponSlot;
if (DebugMode)
{
Debug.Log(item.name + " has been placed as weapon");
}
}
//Removes the weapon from the hand of the Player.
void RemoveWeapon (Item item)
{ if (item.equippedWeaponVersion != null)
{
Destroy(WeaponSlot.FindChild("" + item.equippedWeaponVersion.name).gameObject);
if (DebugMode)
{
Debug.Log(item.name + " has been removed as weapon");
}
}
}
void Update ()
{
//This will turn the character sheet on and off.
if (Input.GetKeyDown(onOffButton))
{
if (csheet)
{
csheet = false;
if (invDispKeyIsSame != true)
{
gameObject.SendMessage ("ChangedState", false, SendMessageOptions.DontRequireReceiver); //Play sound
gameObject.SendMessage("PauseGame", false, SendMessageOptions.DontRequireReceiver); //StopPauseGame/EnableMouse/ShowMouse
}
}
else
{
csheet = true;
if (invDispKeyIsSame != true)
{
gameObject.SendMessage ("ChangedState", true, SendMessageOptions.DontRequireReceiver); //Play sound
gameObject.SendMessage("PauseGame", true, SendMessageOptions.DontRequireReceiver); //PauseGame/DisableMouse/HideMouse
}
}
}
}
//Draw the Character Window
void OnGUI()
{
GUI.skin = cSheetSkin; //Use the cSheetSkin variable.
if(csheet) //If the csheet is opened up.
{
//Make a window that shows what's in the csheet called "Character" and update the position and size variables from the window variables.
windowRect = GUI.Window (1, windowRect, DisplayCSheetWindow, "Character");
}
}
//This will display the character sheet and handle the buttons.
void DisplayCSheetWindow(int windowID)
{
if (canBeDragged == true)
{
GUI.DragWindow (new Rect (0,0, 10000, 30)); //The window is dragable.
}
int index = 0;
foreach(Item a in ArmorSlot) //Loop through the ArmorSlot array.
{
if(a == null)
{
if(GUI.Button(buttonPositions[index], ArmorSlotName[index])) //If we click this button (that has no item equipped):
{
InventoryDisplay id = GetComponent<InventoryDisplay>();
if(id.itemBeingDragged != null) //If we are dragging an item:
{
EquipItem(id.itemBeingDragged,index); //Equip the Item.
id.ClearDraggedItem();//Stop dragging the item.
}
}
}
else
{
if(GUI.Button(buttonPositions[index],ArmorSlot[index].itemIcon)) //If we click this button (that has an item equipped):
{
InventoryDisplay id2 = GetComponent<InventoryDisplay>();
if(id2.itemBeingDragged != null) //If we are dragging an item:
{
EquipItem(id2.itemBeingDragged,index); //Equip the Item.
id2.ClearDraggedItem(); //Stop dragging the item.
}
else if (playersinv.Contents.Count < playersinv.MaxContent) //If there is room in the inventory:
{
UnequipItem(ArmorSlot[index]); //Unequip the Item.
ArmorSlot[index] = null; //Clear the slot.
id2.ClearDraggedItem(); //Stop dragging the Item.
}
else if (DebugMode)
{
Debug.Log("Could not unequip " + ArmorSlot[index].name + " since the inventory is full");
}
}
}
index++;
}
}
}
And I have this error:
Assets/Inventory/Scripts/Character.cs(62,17): error CS0029: Cannot implicitly convert type Item[]' toSystem.Collections.Generic.List'
this lane:
ArmorSlot = new Item[ArmorSlotName.Count];
in JS version there were arrays but in c# i convert it to Lists and i have couple of errors ;D Can someone help me with this ? ;/
Error happens over here.
ArmorSlot = new Item[ArmorSlotName.Count];
What is ArmorSlot?
Private List<Item> ArmorSlot; //This is the built in Array that stores the Items equipped. You can change this to static if you want to access it from another script.
you don't make List like normal array.
You don't want List you want Item array.
Fix is like this
private Item[] ArmorSlot;
But maybe you want List because list is easier to control then a native C# array if you wan't to use List you must do something like this
ArmorSlot = new ArrayList<Item>(ArmorSlotName.Count);
But maybe you don't need to put in ArmorSlotName.Count because List is the size of how much items you put inside it.. it gives default size and keeps increasing.
So it's better to just do this
ArmorSlot = new ArrayList<Item>();
i have one method in class call Class1 like
' public void getEventFromUser() {
int event;
Scanner input = new Scanner(System.in);
date.getDateFromUser();
// od.inputday();
// od.inputyear();
time.getTimeFromUser();
System.out.println("Enter description :");
description = input.nextLine();
}'
and i want to execute this method and store in array in another class
like
public void addEvent() {
if (numEvent == maxEvent) {
System.out.println("error…no more room to add events");
} else {
schedule[numEvent]=getEventFromUser();
int count = 0;
while (count < numEvent - 1) {
if (schedule[numEvent].isEqual(schedule[count])) {
isFound = true;
break;
}
count++;
if (isFound == true) {
System.out.println("Event already exists-notadding");
schedule[numEvent] = null;
} else {
schedule[numEvent].setDate();
schedule[numEvent].setTime();
schedule[numEvent].setDescription();
numEvent++;
//schedule[numEvent]=schedule[numEvent].getEventFromUser();
}
}
}
} '
so,how can i do this?
pls give me some solution
getEventFromUser() doesn't return a value, which is why schedule[numEvent]=schedule[numEvent].getEventFromUser() is giving you trouble.
Without knowing a bit more about what you're trying to do, it's hard to say if you should have getEventFromUser() return a value or have getEventFromUser() directly store a value in a field in the class. (I'm guessing the setDate, setTime and setDescription methods do this.)
I'm making a virtual pet game, and I am now trying to include hunger, however I'm not sure how to make the eat function work. I am trying to make it decrease through the addition of the nutrition value of an item of food. This value is in an object that is stored in an arraylist.
Is there a way to reference
int nutrition(int eaten) {
nutrition = nutrition - eaten;
return nutrition;
(int eaten will be passed in later)
inside
ArrayList items;
void setup() {
items = new ArrayList();
}
void draw() {
for (int i = items.size() - 1; i >=0; i --) {
Food food = (Food) items.get(i);
food.display();
if (food.finished()) {
items.remove(i);
}
}
}
void mouseClicked() {
items.add(new Food(mouseX, mouseY, 1));
}
((Food)items.get(i)).nutrition();
http://www.java-forums.org/new-java/2370-how-return-object-arraylist.html
I've tried to use this, but Processing is unable to find i. I believe this to be because i does not exist in the class, only in the main sketch. If this is so, I will find a way to place i into the method. Maybe using return.
I would appreciate the knowledge if someone was aware of a better way to do this.
CODE
Creature creature;
ArrayList items;
Hand hand;
String data[];
int gameInfo[];
int tempData[];
boolean haveFood;
void setup() {
size(100, 100);
smooth();
noCursor();
String data[] = loadStrings("save.txt");
String[] tempData = split(data[0], ',');
gameInfo = int(tempData);
for (int i = 0; i < data.length; i++) {
creature = new Creature(gameInfo[0], gameInfo[1], gameInfo[2], gameInfo[3]);
haveFood = false;
hand = new Hand();
items = new ArrayList();
}
}
void draw() {
background(255);
for (int i = items.size() - 1; i >=0; i --) {
Food food = (Food) items.get(i);
food.display();
if (food.finished()) {
items.remove(i);
}
}
creature.whatWant();
creature.whatDo(haveFood);
hand.draw();
}
void mouseClicked() {
items.add(new Food(mouseX, mouseY, 1));
haveFood = true;
}
class Creature {
int hunger;
int age;
int gender;
int asleep;
boolean idle;
char want;
char request;
Creature(int _gender, int _age, int _hunger, int _asleep) {
gender = _gender;
age = _age;
hunger = _hunger;
asleep = _asleep;
idle = true;
}
void whatWant() {
if (hunger == 50) {
want = 'H';
}
}
void whatDo(boolean food) {
if (idle == true) {
switch(want) {
case 'H':
if (food == true) {
creature.eat();
}
else
request = 'F';
ask();
}
}
else
{
println("IDLE");
}
}
void ask() {
if (request == 'F') {
println("HUNGRY");
}
}
void eat() {
println("EAT");
((Food)items.get(i)).nutrition();
}
}
class Food {
float posX;
float posY;
int nutrition;
Food(float _posX, float _posY, int rating) {
posX = _posX;
posY = _posY;
nutrition = rating;
}
void display() {
rect(posX, posY, 10, 10);
}
boolean finished() {
if (nutrition < 0) {
return true;
}
else {
return false;
}
}
int nutrition(int eaten) {
nutrition = nutrition - eaten;
return nutrition;
}
}
class Hand {
int posX;
int posY;
Hand() {
posX = mouseX;
posY = mouseY;
}
void draw() {
rectMode(CENTER);
point(mouseX, mouseY);
}
}
Where save.txt is a txt file with 1,1,50,1,1.
Unfortunately I can't provide a nice detailed answer. There are quite a few confusing things with the structure of your project and it's code.
In the meantime, you had a syntax error in the Creature's eat() function.
Try this:
void eat() {
println("EAT");
//((Food)items.get(i)).nutrition();
for(int i = 0 ; i < items.size(); i++){
Food yummy = (Food)items.get(0);
yummy.nutrition(hunger);
}
}
The above works because items is declared at the top and therefore visible through out the scope of the whole sketch(global in other words). I'm not sure if this is intentional or what relationship you plan between creatures and food.
The above can be written in a lazier(but less common/obvious) way like so:
void eat() {
println("EAT");
//((Food)items.get(i)).nutrition();
for(Object yummy : items) ((Food)yummy).nutrition(hunger);
}
I assume the creature will be fed based on how hungry it.
At some point the creature should be full I suppose,
so you would also update the creature's hungry property based on the nutrition
it gets from food, etc.
Also, just to test, I've added very nutritious food :P
items.add(new Food(mouseX, mouseY, 10000));
I have an array of IEnumerable (IEnumerable[]) and would like to generate all possible combinations of the elements in these IEnumerables.
It is similar to this problem: Generating Permutations using LINQ
but I do not know how many IEnumerables I will have beforehand and thus cannot use the described LINQ statement.
To give an example:
My array
IEnumerable[] array;
has for example these elements
array[0]={0,1,2};
array[1]={a,b};
Then I would like these to be returned:
{{0,a},{0,b},{1,a},{1,b},{2,a},{2,b}}
But it might also hold:
array[0]={0,1,2};
array[1]={a,b};
array[2]={w,x,y,z};
Then I would need the appropriate permutations. I do not have any information on how many IEnumerables and no information on how many elements each IEnumerable holds.
Thanks in advance for any help,
Lars
Seems like you want the Cartesian_product. This should work, although I didn't look particularly carefully at edge-cases
public static IEnumerable<T> Drop<T>(IEnumerable<T> list, long numToDrop)
{
if (numToDrop < 0) { throw new ArgumentException("Number to drop must be non-negative"); }
long dropped = 0;
var iter = list.GetEnumerator();
while (dropped < numToDrop && iter.MoveNext()) { dropped++; }
while (iter.MoveNext()) { yield return iter.Current; }
}
public static IEnumerable Concat(object head, IEnumerable list)
{
yield return head;
foreach (var x in list) { yield return x; }
}
public static IEnumerable<IEnumerable> CrossProduct(IEnumerable<IEnumerable> lists)
{
if (lists == null || lists.FirstOrDefault() == null) { yield break; }
var heads = lists.First();
var tails = CrossProduct(Drop(lists, 1));
if (tails.FirstOrDefault() == null)
{
foreach (var h in heads) { yield return new object[] { h }; }
}
else
{
foreach (var head in heads)
{
foreach (var tail in tails)
{
yield return Concat(head, tail);
}
}
}
}
Try this as a direction (you'll need to modify, I'm sure, and I haven't compiled it, so there may be some syntax errors)
public IEnumerable<string> CompileCominations
(IEnumberable<string[]> arrays, List<string> combinations)
{
if(combinations == null) combinations = new List<string>();
for(int i = arrays.Count() - 1; i >= 0; i--)
{
if(combinations.Count >= 1) combinations =
Combine2Lists(combinations, arrays[i]);
else
{
combinations = Combine2Lists(arrays[i], arrays[i -1];
i--;
}
}
return combinations;
}
private List<string> Combine2Lists
(IEnumberable<string> list1, IEnumerable<string> list2)
{
List<string> currentList = new List<string>();
for(int i = 0; i < list1.Count(); i ++)
{
for(int j = 0; j < list2.Count(); j++)
{
currentList.Add(
string.Format("{0},{1}", list1[i], list2[j]);
}
}
return currentList;
}
Again, not compiled, but what it should do is keep adding "item1, item2" to a list with a where item1 = the old "item1, item2" and item2 = just the new entry from the nth array.
Thus string array [a, b, c] + string array [1, 2, 3, 4] should yield: {a, 1}, {a, 2}, {a, 3}, {a, 4}, {b, 1}... and adding string array [x, y, z] to the first to would then yield: {a, 1, x}, {a, 1, y}, {a, 1, z} and so forth.