Укладка предметов в инвентаре игрока (Java, Array / Arraylist) - PullRequest
0 голосов
/ 09 декабря 2011

Редактировать: я получил рабочую версию, используя ArrayList

void addItem(Item item, int count){

        int stacks;

        for (int i = 0; i < useableSlots && count != 0; i++){
            if (itemSlot[i].stack.size() > 0){
                if (itemSlot[i].stack.get(0) == item) {
                    if(itemSlot[i].stack.size() < item.stackLimit){

                        int n = itemSlot[i].stack.size();

                        for(; n < item.stackLimit && count > 0; count--, n++) {
                            itemSlot[i].stack.add(item);
                        }
                    }
                }
            }
            if (i == (useableSlots - 1) && count > 0){
                for(int n = 0; n < useableSlots && count != 0; n++){

                    stacks = ((count - (count % item.stackLimit)) / item.stackLimit);

                    if(itemSlot[n].occupied == false){
                        if(stacks == 0){
                            for(int j = 0; j < count; j++){
                                itemSlot[n].stack.add(item);
                                itemSlot[n].occupied = true;
                            }
                            count = 0;
                        }
                        else {
                            for(int j = 0; j < item.stackLimit; j++){
                                itemSlot[n].stack.add(item);
                            }
                            count -= item.stackLimit;
                            itemSlot[n].occupied = true;
                        }
                    }
                    if (n == (useableSlots - 1)){
                        println("You don't have any room in your inventory");
                    }
                }
            }
        }
    }

.

package com.projects.aoa;

import java.util.*;

public class Itemslot extends Item{

    List<Item> stack = new ArrayList<Item>();
    Item oi = new Item();
    boolean occupied, isArray, full;

}

.

public class Inventory {

    int useableSlots, slots = 50;
    Itemslot[] itemSlot = new Itemslot[slots];


...}

У меня составлен инвентарьмассива Item объектов.Я пытаюсь сделать так, чтобы подобные предметы складывались до определенного предела, прежде чем занять другое место в инвентаре.Я должен идти по этому пути совершенно неправильно, потому что у меня была одна и та же проблема для каждой из моих попыток.Значение hp stackLimit равно 25, (27 hpPotions будут занимать два пространства инвентаря, одно с 25, другое с 2.)

Main

playerOne.backPack.addItem(hpPotion, 20);
playerOne.backPack.printInventory();
playerOne.backPack.addItem(hpPotion, 15);
playerOne.backPack.printInventory();

Item.java

package com.projects.aoa;

import static com.projects.aoa.Print.*;

import java.util.*;
import java.io.*;

class Item {

//Item
String name, type, category;
int id;
int hp, mp, str, def, duration;

//Inventory
public boolean filled;
public int count, stackLimit;

static void getAllStats(Item[] e){
    for(Item i : e){
        getItemStats(i);
    }
}

static void getItemStats(Item i){
    i.getStats();
}

void getStats(){
    try {
        //System.out.println(System.getProperty("user.dir"));

        FileInputStream fstream = new FileInputStream(System.getProperty("user.dir") 
                + "/src/com/projects/aoa/" + this.type + "_" + this.name + ".txt");

        DataInputStream in = new DataInputStream(fstream);

        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        String line;
        int counter = 0;

        while ((line = br.readLine()) != null) {
            if (line.length() == 0){
                break;
            }

            switch (counter) {
            case 0:
                this.hp = Integer.parseInt(line);
                counter++;
                break;
            case 1:
                this.mp = Integer.parseInt(line);
                counter++;
                break;
            case 2:
                this.def = Integer.parseInt(line);
                counter++;
                break;
            case 3:
                this.str = Integer.parseInt(line);
                counter++;
                break;
            case 4:
                this.stackLimit = Integer.parseInt(line);
                counter++;
                break;
            case 5:
                this.duration = Integer.parseInt(line);
                counter++;
                break;
            }   
        }


        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

void printStats(){
    println("[" + name + "]");
    println("Type: " + type);
    println("Duration: " + duration);
    println("HP:  " + hp);
    println("MP:  " + mp);
    println("Def: " + def);
    println("Str: " + str);
}
}

Вывод инвентаря: 3-я попытка

addItem (hpPotion, 20);

[1]  Mallet              [2]  BronzeHelmet        [3]  hpPotion(20)        [4]  Empty               [5]  Empty               

[6]  Empty               [7]  Empty               [8]  Empty               [9]  Empty               [10] Empty               

[11] Empty               [12] Empty               [13] Empty               [14] Empty               [15] Empty               

[16] Empty               [17] Empty               [18] Empty               [19] Empty               [20] Empty  

addItem (hpPotion, 15);

[1]  Mallet              [2]  BronzeHelmet        [3]  hpPotion(10)        [4]  hpPotion(10)        [5]  Empty               

[6]  Empty               [7]  Empty               [8]  Empty               [9]  Empty               [10] Empty               

[11] Empty               [12] Empty               [13] Empty               [14] Empty               [15] Empty               

[16] Empty               [17] Empty               [18] Empty               [19] Empty               [20] Empty 

То же самое происходит во второй попытке, за исключением того, что появляется добавление двух

[3]  hpPotion(35)        [4]  hpPotion(35)

Кажется, что это будет просто простое исправление (и, возможно, так оно и есть),но я просто понятия не имею, что это может быть.Любая помощь приветствуется.

Третья попытка

void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    for(int i = 0; i < 20; i++){
        if(itemSlot[i] == item && count > 0){
            room = (item.stackLimit - itemSlot[i].count);
            if(room > 0){
                if(count >= room){
                    itemSlot[i].count += room;
                    count -= room;
                }
                else if(count > 0 && count < room){
                    itemSlot[i].count += count;
                    count = 0;
                    break;
                }
            }
        }

        if(i >= 19 && count > 0){
            for(int n = 0; n < 20; n++){
                if(itemSlot[n].filled == false){
                    int stacks = ((count - (count % item.stackLimit)) / 25);
                    println(stacks);
                    if (stacks == 0){
                        itemSlot[n] = item;
                        itemSlot[n].filled = true;
                        itemSlot[n].count = count;
                        count = 0;
                        break;
                    }
                    else {
                        itemSlot[n] = item;
                        itemSlot[n].filled = true;
                        itemSlot[n].count = item.stackLimit;
                        count -= item.stackLimit;
                    }
                }
            }
        }
    }
}

Вторая попытка

    void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    outerLoopCurrentStack:
    for(int i = 0; i < 20; i++) {
        if(itemSlot[i].name == item.name){
            if(itemSlot[i].count < itemSlot[i].stackLimit){

                while(count > 0){
                    count--;
                    itemSlot[i].count++;

                    if(itemSlot[i].count == itemSlot[i].stackLimit) {
                        break outerLoopCurrentStack;
                    }
                }
            }
        }
        else if((i >= 19) && (count > 0)){
            newStack = true;
        }
    }

    if(newStack = true){

        outerLoopNewStack:
        for(int i = 0; i < 20; i++){
            if(itemSlot[i].filled == false){

                itemSlot[i] = item;
                itemSlot[i].filled = true;

                while(count > 0){
                    count--;
                    itemSlot[i].count++;

                    if(count == 0){
                        newItem = false;
                        count = 0;
                        break outerLoopNewStack;
                    }
                }
            }
        }
    }
}
     }  

Первая попытка

    void addItem(Item item, int count){

    boolean newStack = false;

    int room, totalCount = 0;

    for (int i = 0; i < 20; i++){
        if(itemSlot[i].name == item.name) {
            if(itemSlot[i].count < item.stackLimit){
                room = (item.stackLimit - itemSlot[i].count);
                if (count > room){
                    itemSlot[i].count += room;
                    itemSlot[i].filled = true;
                    count -= room;
                }
                else {
                    itemSlot[i].count += count;
                    break;
                }
            }
        }
        else if(i == 19){
            newStack = true;
        }
    }

    if (newStack == true){
        for(int i = 0; i < 20; i++){
             if(itemSlot[i].filled == false) {
                if(count > item.stackLimit){
                    itemSlot[i] = item;
                    itemSlot[i].count = item.stackLimit;
                    itemSlot[i].filled = true;
                    count -= item.stackLimit;
                }
                else{
                    itemSlot[i] = item;
                    itemSlot[i].count = count;
                    itemSlot[i].filled = true;
                    break;
                }
            }
        }
    }
     }

Ответы [ 3 ]

2 голосов
/ 09 декабря 2011

Похоже, вы помещаете один и тот же объект в оба слота инвентаря, поэтому, когда вы меняете члена .count, он меняет его в обоих слотах.

Первый признак состоит в том, что вы сравниваете существующийэлемент к тому, который вставляется с ==.Если вы переполнены, попробуйте изменить

itemslot[i] = new Item(item);

вместо

itemslot[i] = item;

Если у вас есть конструктор копирования.

1 голос
/ 09 декабря 2011

Хорошо, я думаю, что есть 2 возможных способа сделать это, и я, вероятно, сделал бы это по-другому.

Альтернативный метод
Я бы абстрагировал механику рюкзака от реального хранилища данных. Для этого мне нужен либо массив, либо словарь. Я бы, вероятно, использовал словарь для выполнения { item => count }, но я понимаю, что это может быть нецелесообразно, если у вас есть конкретные данные, хранящиеся с каждым экземпляром каждого элемента.

Из этого хранилища данных при представлении пользователю через интерфейс или другому коду, который может проверять, заполнен ли рюкзак, вы можете просто выполнить итерацию по словарю, генерируя текущий счетчик количества занятых пробелов. Я думаю, что это лучший способ сделать это.

Редактировать : Я думаю, что этот метод не совсем понятен, о чем @EdwinBuck упомянул в своем ответе.

Однако, это может быть непрактично для вашего приложения (игры), и поэтому я надеюсь, что следующий базовый алгоритм может вам помочь. Я не знаю, работает ли он отлично, и, возможно, он не очень эффективен, но я сомневаюсь, что рюкзаки будут достаточно большими, чтобы это имело значение.

def addItem(item, count)

    foreach (slot in backpack)
        if (slot.type = Array<Item>)
            if (slot.count < max)

                // Enough space to add at least one more
                if (count > 1)
                    foreach (count) addItem(item, 1)
                    // yes this is recursive to get the checking
                else
                    slot.add(item)
                end

            else

                // Not enough space, create a new slot
                var newSlot
                backpack.add(newSlot)

                if (count > 1)
                    foreach (count) addItem(item, 1)
                    // yes this is recursive to get the checking
                else
                    newSlot.add(item)
                end 

            end
        end
    end
end
1 голос
/ 09 декабря 2011

Посмотрите на составной паттерн , где предметы находятся в «содержимом» инвентаря.

Тогда вы можете иметь сумку, которая «содержится» в содержимом пользователя, в то же время имея содержимое, которое содержится в сумке.

Такие вещи верхнего уровня, как вычисление веса, будут суммировать вес каждого элемента в текущем контейнере. Если для этого требуется запросить у элемента, который является контейнером, его вес, контейнер-элемент будет рассчитывать его вес, используя ту же методику (пока в конечном итоге неконтейнерные элементы просто не сообщат свои не рассчитанные веса).

В любом случае, вы хотите уйти от массивов для коллекций, которые демонстрируют поведение, так как вы не можете добавить поведение в коллекцию с массивом, а наличие его снаружи (в куче методов) в конечном итоге сделает ваш код трудно поддерживать / исправить / изменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...