如何修复 FileInputStream 只查看最后一个条目?

How to fix FileInputStream only looking at last entry?

我正在尝试制作我的游戏组喜欢的纸牌游戏的简单版本,以便我们的肢体残疾朋友可以参加游戏之夜。但是,当我尝试使用 while(inputStream.hasNextLine()).

通过文本文件将卡片数据值添加到 ArrayList 时,我遇到了 FileInputStream 似乎只读取文本文件的最后一行的问题

我正在尝试将值打印为卡片 class 中我的 cardToString() 方法中定义的字符串。该代码当前使用 cardToString() 方法打印文件中的最后一张卡片,
ID: 71 Card: 72 Stack: Door Type: Power Name: Power Absorption Power: Rank 3 Text: You may discard a card to try to steal a Power carried by another player. Roll the die; 4 or higher succeeds. Otherwise, you get caught and lose a Level. Bonus: 3
,用于所有 72 张卡片。第一项的名称应为 "Gradydon Creed",最后一个输出的名称应为 "Power Absorption"

如有任何帮助,我们将不胜感激!

这是我的主要方法class:

private static int stack, type, name, text, bad, level, treasure, pLevel, modifier, rank;

public static void main(String[] args) {  

Deck deck = new Deck();

try {
    Scanner inputStream = null;

    inputStream = new Scanner(new FileInputStream("MunchkinIDSheet.txt"));

    while(inputStream.hasNextLine()){
        stack = inputStream.nextInt();
        type = inputStream.nextInt();
        name = inputStream.nextInt();
        text = inputStream.nextInt();
        bad = inputStream.nextInt();
        level = inputStream.nextInt();
        treasure = inputStream.nextInt();
        pLevel = inputStream.nextInt();
        modifier = inputStream.nextInt();
        rank = inputStream.nextInt();

    deck.addCard(new Card(stack, type, name, text, bad, level, treasure, pLevel, modifier, rank));
    }

    inputStream.close();
}
catch (Exception e) {
    System.out.println(e);
}

deck.list();
}

我的套牌class:

import java.util.ArrayList;

public class Deck {
private static ArrayList<Card> deck = new ArrayList<>();

public void addCard(Card n){
    deck.add(n);
}

public static void list(){
    for(int i = 0; i < deck.size(); i++){
        System.out.println("ID: " + i + "\n" + "Card: " + (i + 1) + "\n" + Card.cardToString(deck.get(i)));
        System.out.println();
    }
  }
}

我的名片class: public class 卡片{

private static int stack, type, name, text, bad, level, treasure, pLevel, modifier, rank;

private static final int DOOR = 1;
private static final int TREASURE = 2;

private static final int MONSTER = 1;
private static final int AFFILIATION = 2;
private static final int WANDERING = 3;
private static final int TEAMUP = 4;
private static final int MODIFIER = 5;
private static final int CHEAT = 6;
private static final int TRAP = 7;
private static final int POWER = 8;

private static String trs = " Treasure", pdac = "Play during any combat.\n", p = "Power: Rank ";

public Card(){
    stack = -1;
    type = -1;
    name = -1;
    text = -1;
    bad = -1;
    level = -1;
    treasure = -1;
    pLevel = -1;
    modifier = -1;
    rank = -1;
}

public Card(int stack, int type, int name, int text, int bad, int level, int treasure, int pLevel, int modifier, int rank){
    this.stack = stack;
    this.type = type;
    this.name = name;
    this.text = text;
    this.bad = bad;
    this.level = level;
    this.treasure = treasure;
    this.pLevel = pLevel;
    this.modifier = modifier;
    this.rank = rank;
}


public static String getStackAsString(int stack){
    switch( stack ) {
        case DOOR: return "Door";
        case TREASURE: return "Treasure";
        default: return "Unknown Stack";
    }
}

public static String getTypeAsString(int type) {
    switch( type ) {
        case MONSTER: return "Monster";
        case AFFILIATION: return "Affiliation";
        case WANDERING: return "Wandering";
        case TEAMUP: return "Team-Up";
        case MODIFIER: return "Modifier";
        case CHEAT: return "Cheat";
        case TRAP: return "Trap";
        case POWER: return "Power";
        default: return "Unknown Type";
    }
}

public static String getNameAsString(int name){
    switch ( name ) {
        case 0: return "Graydon Creed";
        case 1: return "Toad";
        case 2: return "Bolivar Trask";
        case 3: return "Sentinel MK I";
        case 4: return "William Stryker";
        case 5: return "Sauron";
        case 6: return "Black Tom Cassidy";
        case 7: return "Sentinel MK III";
        case 8: return "Silver Samurai";
        case 9: return "Pyro";
        case 10: return "Omega Red";
        case 11: return "The Brood";
        case 12: return "Sentinel MK V";
        case 13: return "Mojo";
        case 14: return "Lady Deathstrike";
        case 15: return "Sebastian Shaw";
        case 16: return "Blob";
        case 17: return "Mystique";
        case 18: return "Sabretooth";
        case 19: return "Phalanx";
        case 20: return "Juggernaut";
        case 21: return "Emma Frost";
        case 22: return "Nimrod";
        case 23: return "Bastion";
        case 24: return "Master Mold";
        case 25: return "Mister Sinister";
        case 26: return "Stryfe";
        case 27: return "Magneto";
        case 28: return "Onslaught";
        case 29: return "X-Men";
        case 31: return "X-Factor";
        case 33: return "X-Force";
        case 35: return "Wandering Monster";
        case 38: return "Team-Up";
        case 40: return "Invincible...";
        case 41: return "Uncanny...";
        case 42: return "Unstoppable...";
        case 43: return "New and Improved...";
        case 44: return "Vulnerable...";
        case 45: return "Cheat!";
        case 46: return "Illusion!";
        case 47: return "Evolutionary War";
        case 48: return "Mutant Massacre";
        case 49: return "Mojoworld";
        case 50: return "Brotherhood of Evil Mutants";
        case 51: return "Hellfire Club";
        case 52: return "X-Cutioner's Song";
        case 53: return "Techno-Virus";
        case 54: return "Weapon X Program";
        case 55: return "Disarmed";
        case 56: return "X-Tinction Agenda";
        case 57: return "Arcade's Murderworld";
        case 58: return "Legacy Virus";
        case 59: return "Mutant Registration Act";
        case 60: return "Flight";
        case 61: return "Optic Blasts";
        case 62: return "Telepathy";
        case 63: return "Heightened Senses";
        case 64: return "Healing Factor";
        case 65: return "Super-Agility";
        case 66: return "Energy Blasts";
        case 67: return "Telekinesis";
        case 68: return "Super-Strength";
        case 69: return "Elemental Control";
        case 70: return "Teleportation";
        case 71: return "Power Absorption";
        default: return "Unknown Name";
    }
}

public static String getTextAsString(int text){
    switch ( text ) {
        case 0: return "Mystique and Sabretooth may join him in combat without the use of a Wandering Monster card.";
        case 1: return "When he enters combat, roll the die.  On a 1-3, he ges +3.  On a 4-6, the player(s) in combat must discard a card.";
        case 2: return "+2 for each Sentinel in the Door discards.  You may discard this card to give a Sentinel +5.";
        case 3: return "+1 for each Ally and Power of the player(s) in combat.  You may discard this card to give a Sentinel +5.";
        case 4: return "+5 against players with no Affiliation";
        case 5: return "When he enters combat, the player(s) in combat must discard an Ally.";
        case 6: return "+6 if there is a living plant in the room.";
        case 7: return "+2 for each Ally and Power of the player(s) in combat.  You may discard this card to give a Sentinel +5.";
        case 8: return "+5 against anyone wearing Armor.  -2 against anyone with both Hands equipped.";
        case 9: return "+6 if there is an open flame in the room or a lighter on the table.";
        case 10: return "+4 against anyone who is not wearing the color red.  -1 to run away.";
        case 11: return "Hive mind!  Each player may discard one card to give The Brood +3.";
        case 12: return "+3 for each Ally and Power of the player(s) in combat.  You may discard this card to give a Sentinel +5.";
        case 13: return "+5 if there is a television in the room.  An extra +5 if it is on.";
        case 14: return "+4 against males or players not wearing Armor.  -3 against Wolverine.";
        case 15: return "+3 against X-Men.  +1 for each card the player(s) in combat have in hand and in play when he enters combat.";
        case 16: return "+3 if there is any candy or soda on the table when he enters combat.  +6 if both.";
        case 17: return "No one may help you fight her.  +3 against males.  -2 against females.";
        case 18: return "Combat bonuses played on him are worth an extra +2.";
        case 19: return "+3 for each electronic device on the table when they enter combat.";
        case 20: return "+10 if he enters combat via a Wandering Monster card.  -1 to run away.";
        case 21: return "-3 against X-Men.  +3 against females.  +6 against anyone wearing a diamond or the color white.";
        case 22: return "+2 for each Ally and Power in play.  Counts as a Sentinel.  You may discard this card to give a Sentinel +5.";
        case 23: return "+10 if Master Mold or Nimrod is in the Door discards.  Counts as a Sentinel.  You may discard this card to give a Sentinel +5.";
        case 24: return "+4 against anyone with an Affiliation.  Counts as a Sentinel.  You may discard this card to give a Sentinel +10.";
        case 25: return "He knows all your plans.  Players may not use One-Shots to aid their side in combat.";
        case 26: return "+5 against X-Factor.  -3 against X-Force.";
        case 27: return "+4 for each player in combat with at least 500 gold pieces worth of items in play.";
        case 28: return "When he enters combat, lose an Ally or Power, and he gets its bonus.  -5 against Professor X.  Will not pursue anyone Level 4 or below.";
        case 29: return "You may have two extra ranks worth of Powers.\n\nWhen another player discards an Ally, you may discard two cards and put that Ally in your hand.";
        case 31: return "When you play a Trap from your hand,you may choose to apply its effect to all players(including yourself).\n\nWhen you play a Go Up A Level card, you may discard a card to force another player to lose a Level.";
        case 33: return "Each of your Hand items is worth an additional +1.\n\nOnce per combat, you may discard a card to give either side +2.";
        case 35: return "Play this card, with a Monster from your hand, when someone (including you!) is in combat.  Your Monster joins the one already fighting.\n--\nAdd their combat strengths.\n\nIf the player(s) must flee, resolve the run away attempts separately, in the order the victim chooses.";
        case 38: return "You may have two Affiliation cards, and have all of the advantages and disadvantages of each.  OR you may have one Affiliation card and have all of its advantages and none of its disadvantages.\n\nLose this card if you lose your Affiliation card(s).";
        case 40: return "+10 to Monster\n" + pdac + "If the Monster is defeated, draw two extra Treasures.";
        case 41: return "+10 to Monster\n" + pdac + "If the Monster is defeated, draw two extra Treasures.";
        case 42: return "+5 to Monster\n" + pdac + "If the Monster is defeated, draw one extra Treasure.";
        case 43: return "+5 to Monster\n" + pdac + "If the Monster is defeated, draw one extra Treasure.";
        case 44: return "-5 to Monster\n" + pdac + "If the Monster is defeated, draw one fewer Treasure.  (Minimum of 1)";
        case 45: return "Play this card with an item you have in play or an item from your hand.\n\nThis item is legal for you to use even if it otherwise would not be.  Discard this card when you lose (sell, etc.) the attached item.";
        case 46: return pdac + "\nDiscard any one Monster in this combat, along with any cards that have been played to modify it, and replace with a Monster card from you hand.";
        case 47: return "Only the strongest survive.  Lose all items and Allies except for the item and Ally giving you the biggest bonus.  Choose one of each in case of ties.";
        case 48: return "Lose an Ally.  If you have no Allies, lose a Level.";
        case 49: return "Change the channel!  Immediately exchange all cards in hand and Allies in play with the player to your right.";
        case 50: return "You have -5 in your next combat.  Keep this in front of you as a reminder.";
        case 51: return "Your secrets have been revealed!  Lose your Affiliation(s).  If you have none, lose a Level.";
        case 52: return "Lose the Headgear you are wearing.  If you have no Headgear, lose a Level.";
        case 53: return "Lose Items worth at least 500 gold pieces.";
        case 54: return "You have -5 in your next combat, or -10 against Monsters Level 5 or below.  Keep this card in front of you as a reminder.";
        case 55: return "Lose an equipped Hand Item.";
        case 56: return "Suffer the Bad Stuff of the topmost Monster in the Door discards.";
        case 57: return "Roll the die.  On a 1, you are dead.  Otherwise, discard that many cards from your hand.";
        case 58: return "Lose two Levels.";
        case 59: return "Lose a Power and a Level.";
        case 60: return "You have +1 to run away.";
        case 61: return "An extra +1 if you are wearing glasses.";
        case 62: return "Discard one card from your hand at any time to see all of the cards in any one player's hand.";
        case 63: return "Each time you reveal a Trap, when kicking open the Door, you may roll the die.  On a 5 or higher, cancel the Trap.";
        case 64: return "If you would lose a Level or die due to a Trap or Bad Stuff, roll the die.  On a 5 or higher, cancel the effect and instead Go Up A Level!  This cannot be the winning Level.";
        case 65: return "You have +2 to run away.";
        case 66: return "You may discard up to three cards in combat, each for an extra +1";
        case 67: return "You may discard a card to try to steal an Item carried by another player.  Roll the die; 4 or higher succeeds.  Otherwise, you get caught and lose a Level.";
        case 68: return "Each empty Hand your character has is worth an extra +2.";
        case 69: return "\"Power seethes in the roiling clouds.\"";
        case 70: return "You may discard a card to try to steal an Item carried by another player.  Roll the die; 4 or higher succeeds.  Otherwise, you get caught and lose a Level.";
        case 71: return "You may discard a card to try to steal a Power carried by another player.  Roll the die; 4 or higher succeeds.  Otherwise, you get caught and lose a Level.";
        default: return "Unknown Text";
    }
}

public static String getBadAsString(int bad){
    switch ( bad ) {
        case 0: return "Lose a card giving you the smallest bonus.";
        case 1: return "Toxic spit!  Discard a random card from your hand.";
        case 2: return "Lose an Ally or a Power.";
        case 3: return "Lose a Level.";
        case 4: return "Captured for government experiments.  You have -5 in your next combat for each of your Powers.";
        case 5: return "Energy vampire!  Lose a Power.";
        case 6: return "Shillelaghed!  Lose your Headgear.  If you aren't wearing any, discard two cards from your hand.";
        case 7: return "Lose a Level and discard a card.";
        case 8: return "Lose your Armor.  If you aren't wearing any, lose a Level.";
        case 9: return "Too hot to handle!  Discard three cards from you hand.";
        case 10: return "Lose the card giving you the biggest bonus.";
        case 11: return "Swarmed!  Roll the die and discard that many cards.";
        case 12: return "Lose a Level.  You have -5 in your next combat.";
        case 13: return "Enslaved by the Spineless Ones.  Lose your Affiliation.  If you have none, lose a Level.";
        case 14: return "You are dead.";
        case 15: return "Roll the die and discard that many cards.";
        case 16: return "He sits on you.  The next time you attempt to run away, you automatically fail.";
        case 17: return "No one believes it is really you.  You cannot offer to help or ask for help in combat until you go up a Level.";
        case 18: return "He rips you to shreds!  You are dead!";
        case 19: return "Lose all your Allies to the Techno-Virus.  If you have none, lose a Level.";
        case 20: return "Nothing stops the Juggernaut!  Lose the Armor you are wearing and a Level.";
        case 21: return "Reveal you hand.  The player to your left chooses two cards for you to discard.";
        case 22: return "Lose an Ally, a Power, and a Level.";
        case 23: return "Lose a Level, plus an additional Level for each Sentinel in the Door discards.";
        case 24: return "Lose three Levels.";
        case 25: return "Go back in time and suffer the Bad Stuff of the top two Monsters in the Door discards.";
        case 26: return "Lose your Affiliation and discard items worth at least 500 gold pieces.";
        case 27: return "Lose all items worth 300 gold pieces or more.";
        case 28: return "Lose two Levels and discard two cards from your hand.";
        default: return "Unkown Bad Stuff";
    }
}

public static String cardToString(Card c){
    switch ( type ) {
        case MONSTER:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nLevel: " + getLevel() + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text) + "\nBad Stuff: " + getBadAsString(bad) + "\nTreasure: " + getTreasure() + trs + "\nPlayer Level: +" + getPLevel();
        case AFFILIATION:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text);
        case WANDERING:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text);
        case TEAMUP:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text);
        case MODIFIER:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text) + "\nModifier: " + getModifier();
        case CHEAT:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text);
        case TRAP:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\nText: " + getTextAsString(text);
        case POWER:
            return "Stack: " + getStackAsString(stack) + "\nType: " + getTypeAsString(type) + "\nName: " + getNameAsString(name) + "\n" + p + getRank() + "\nText: " + getTextAsString(text) + "\nBonus: " + getModifier();
        default:
            return "Unknown Card";
    }
}

/**
 * @return the stack
 */
public static int getStack() {
    return stack;
}

/**
 * @return the type
 */
public static int getType() {
    return type;
}

/**
 * @return the name
 */
public static int getName() {
    return name;
}

/**
 * @return the text
 */
public static int getText() {
    return text;
}

/**
 * @return the bad
 */
public static int getBad() {
    return bad;
}

/**
 * @return the level
 */
public static int getLevel() {
    return level;
}

/**
 * @return the treasure
 */
public static int getTreasure() {
    return treasure;
}

/**
 * @return the pLevel
 */
public static int getPLevel() {
    return pLevel;
}

/**
 * @return the modifier
 */
public static int getModifier() {
    return modifier;
}

/**
 * @return the rank
 */
public static int getRank() {
    return rank;
}

}

最后是文本文件中的数据值,在代码中保存为"MunchkinIDSheet.txt":

1 1 0 0 0 0 0 1 0 0
1 1 1 1 1 1 1 10 0
1 1 2 2 2 2 2 1 0 0
1 1 3 3 3 3 3 1 0 0
1 1 4 4 4 4 4 1 0 0
1 1 5 5 5 5 5 1 0 0
1 1 6 6 6 6 6 1 0 0
1 1 7 7 7 7 7 1 0 0
1 1 8 8 8 8 8 1 0 0
1 1 9 9 9 9 9 1 0 0
1 1 10 10 10 10 10 1 0 0
1 1 11 11 11 11 11 1 0 0
1 1 12 12 12 12 12 1 0 0
1 1 13 13 13 13 13 1 0 0
1 1 14 14 14 14 14 1 0 0
1 1 15 15 15 15 15 1 0 0
1 1 16 16 16 16 16 1 0 0
1 1 17 17 17 17 17 1 0 0
1 1 18 18 18 18 18 1 0 0
1 1 19 19 19 19 19 1 0 0
1 1 20 20 20 20 20 1 0 0
1 1 21 21 21 21 21 1 0 0
1 1 22 22 22 22 22 1 0 0
1 1 23 23 23 23 23 1 0 0
1 1 24 24 24 24 24 1 0 0
1 1 25 25 25 25 25 2 0 0
1 1 26 26 26 26 26 2 0 0
1 1 27 27 27 27 27 2 0 0
1 1 28 28 28 28 28 2 0 0
1 2 29 29 -1 -1 -1 0 0 0
1 2 29 29 -1 -1 -1 0 0 0
1 2 31 31 -1 -1 -1 0 0 0
1 2 31 31 -1 -1 -1 0 0 0
1 2 33 33 -1 -1 -1 0 0 0
1 2 33 33 -1 -1 -1 0 0 0
1 3 35 35 -1 -1 -1 0 0 0
1 3 35 35 -1 -1 -1 0 0 0
1 3 35 35 -1 -1 -1 0 0 0
1 4 38 38 -1 -1 -1 0 0 0
1 4 38 38 -1 -1 -1 0 0 0
1 5 40 40 -1 -1 -1 0 10 0
1 5 41 41 -1 -1 -1 0 10 0
1 5 42 42 -1 -1 -1 0 5 0
1 5 43 43 -1 -1 -1 0 5 0
1 5 44 44 -1 -1 -1 0 -5 0
1 6 45 45 -1 -1 -1 0 0 0
1 14 46 46 -1 -1 -1 0 0 0
1 7 47 47 -1 -1 -1 0 0 0
1 7 48 48 -1 -1 -1 0 0 0
1 7 49 49 -1 -1 -1 0 0 0
1 7 50 50 -1 -1 -1 0 0 0
1 7 51 51 -1 -1 -1 0 0 0
1 7 52 52 -1 -1 -1 0 0 0
1 7 53 53 -1 -1 -1 0 0 0
1 7 54 54 -1 -1 -1 0 0 0
1 7 55 55 -1 -1 -1 0 0 0
1 7 56 56 -1 -1 -1 0 0 0
1 7 57 57 -1 -1 -1 0 0 0
1 7 58 58 -1 -1 -1 0 0 0
1 7 59 59 -1 -1 -1 0 0 0
1 8 60 60 -1 -1 -1 0 1 1
1 8 61 61 -1 -1 -1 0 1 1
1 8 62 62 -1 -1 -1 0 1 1
1 8 63 63 -1 -1 -1 0 1 1
1 8 64 64 -1 -1 -1 0 1 2
1 8 65 65 -1 -1 -1 0 2 2
1 8 66 66 -1 -1 -1 0 1 2
1 8 67 67 -1 -1 -1 0 2 2
1 8 68 68 -1 -1 -1 0 2 3
1 8 69 69 -1 -1 -1 0 4 3
1 8 70 70 -1 -1 -1 0 3 3
1 8 71 71 -1 -1 -1 0 3 3

这是一个不错的项目。

您的问题是您误用了 static 关键字。基本上,您将每个值设为 Card class 的 属性 而不是单个 Card 实例Here's 很好地解释了它是如何工作的。

此外,Java 具有将对象表示为字符串的内置功能,即 toString() 方法。如果你用它代替 Card.cardToString(),它会让你的生活更轻松。

这是一个 CardDeck 的基本示例,可为您指明正确的方向。

// Card.java
public class Card {
    // An array containing information about cards in general should be static.
    private static String[] NAMES = new String[]{"Card 1", "Card 2"/*, ...*/};
    private static String[] TEXTS = new String[]{"Card 1 description", "Card 2 description"/*, ...*/};

    // These values, which are unique to each card, are not static.
    private int name, text; 

    public Card(int name, int text) {
        this.name = name;
        this.text = text;
    }

    public String toString() {
        // Instead of having cardToString(), we use this canonical function.
        return Card.NAMES[this.name] + ' ' + Card.TEXTS[this.description];
    }
}

// Deck.java
public class Deck {
    // Since there could be many decks, each with their own cards, this isn't static either.
    private List<Card> cards;

    public Deck() {
        this.cards = new ArrayList();
    }

    public void addCard(Card card) {
        this.cards.add(card);
    }

    public String toString() {
        String str = "";
        for (int i = 0; i < this.cards.size(); i++) {
            str += this.cards.get(i) + "\n";
        }
        return str;
    }
}

然后,我们可以在我们的主要方法中说:

Deck deck = new Deck();
deck.addCard(new Card(0, 0));
// Etc...
System.out.println(deck);