2011-06-24 2 views
0

前の質問のフォローアップ戦闘シミュレータについて投稿しました。スレッドマネージドオブジェクトが別のスレッドのスタックに入っていない

ここでの問題は、「クリーチャー」オブジェクトが「戦闘」クラスのスタックに入らないことです。

すべてのことがいくつかのクラスが大きいですが、私は問題を次のコードに絞り込むことができました。

public class Combat implements Runnable { 
int Turn = 0; 
HashMap<Integer, Faction> Factions = new HashMap<Integer, Faction>(); 
Stack<Creature> stack; 

public int getFactionsStanding() { 
    int Result = 0; 

    Iterator<Faction> F = Factions.values().iterator(); 

    while(F.hasNext()) { 
     if (F.next().getMemberCount() > 0) 
      Result = Result + 1; 
    } 

    return Result; 
} 

public HashMap<Integer, Creature> getEnemies(int factionID) throws NoFactionsException { 
    HashMap<Integer, Creature> targetPool = new HashMap<Integer, Creature>(); 

    Iterator<Faction> F = Factions.values().iterator(); 

    if (!(F.hasNext())) 
     throw new NoFactionsException(); 

    Faction tempFaction; 

    while (F.hasNext()){ 
     tempFaction = F.next(); 

     if (tempFaction.getfactionID() != factionID) 

      targetPool.putAll(tempFaction.getMembers());     
    } 

    return targetPool; 
} 

private int getMaxInit(){ 
    int Max = 0, temp = 0; 
    Iterator<Faction> I = Factions.values().iterator(); 

    while(I.hasNext()){ 
     temp = I.next().getMaxInit(); 
     if (temp > Max) 
      Max = temp;    
    }   

    return Max; 
} 

public int getTurn() { 
    return Turn; 
} 

public void setTurn(int turn) { 
    Turn = turn; 
} 

// TODO I can't get creatures to enter the stack! :@ 
synchronized public void push(Creature C){ 
    stack.push(C); 

    System.out.println("Creature " + C.getName() + " is now on the stack"); 

    if (C.getInit() == this.getMaxInit()) 
     this.emptyStack(); 

    notify(); 
} 

// TODO The stack must be processed now: everyone does what they intended to do 
public void emptyStack(){ 
    Creature C; 

    while (!(stack.isEmpty())){ 
     C = stack.pop(); 

     C.takeAction(); 
    } 

    Turn = 0;  
} 

synchronized public void increaseTurn(){ 
    this.Turn = Turn + 1; 

    System.out.println("Current initiative score is " + this.getTurn()); 

    notifyAll(); 

    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     return; 
    } 

} 


    public void run(){ 
    while(this.getFactionsStanding() > 1){ 
     increaseTurn(); 
    } 
} 
} 

public class Creature extends Observable implements Runnable { 

     synchronized public void declareAction(){ 
    try{ 
     if (Combat.getTurn() != this.getInit()) 
      wait();     

     Combat.push(this); 
    } 
    catch (InterruptedException e){ 
     return; 
    } 
} 

public void takeAction(){ 
    Attack(this.Target, this.leftHandWeapon); 

    if (this.Target.getCurrentHP() < 0) 
     this.Target = null; 
} 

public void setTarget() { 
    Integer targetID = -1; 
    HashMap<Integer, Creature> targetPool; 
    Object[] targetKeys; 

    try{ 
     targetPool = Combat.getEnemies(FID); 

     if (targetPool.isEmpty()) 
      throw new EmptyTargetPoolException(); 

     targetKeys = targetPool.keySet().toArray(); 

     if (targetKeys.length == 0) 
      throw new EmptyTargetKeysArrayException(); 

     if (this.Target == null) { 
      do{ 
       targetID = (Integer) this.getRandom(targetKeys); //(Integer)targetKeys[(Integer) this.getRandom(targetKeys)]; 
      } while (!(targetPool.keySet().contains((Integer)targetID))); 

      this.Target = targetPool.get(targetID); 
     } 
    } 
    catch (EmptyTargetPoolException e) { 
     System.out.println(e.getMessage()); 
    } 
    catch (EmptyTargetKeysArrayException e) { 
     System.out.println(e.getMessage()); 
    } 
    catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 

} 

public void run() { 
    // This will go on and on as long as this creature is alive 
    while (this.currentHP > 0) { 
     try { 
      this.setInit(); 

      this.setTarget(); 

      this.declareAction();      
     } 
     catch (Exception e){ 
      System.out.println(e.getMessage()); 
     } 
    }  

    System.out.println(this.Name + " was killed!");  
} 

}

+0

これらのクラスはスレッドセーフではありません。 –

答えて

0

生き物は、プリントアウトします名前を付けていますか?これに問題がある可能性がある場合:)(

if (C.getInit() == this.getMaxInit()) 
    this.emptyStack(); 

私は、メソッドgetInit()は何をするかわからないけどgetMaxInitは()も同じ値を返す場合、それは単にスタックたびプッシュを空にできが呼び出されます。私が今見ることができる唯一の問題は起こる可能性があります。

+0

GetInit()は、クリーチャーのイニシアチブスコアを表す整数値を返します(例えば、反応する速さなど)。最高得点のクリーチャーは最後にスタックに入り、最初に行動するはずです。 –

+0

問題が表示されません。私の助言は、それぞれの方法をテストして、それがあなたが思っていることを確実にするかどうかをテストすることです。その問題を絞り込むための唯一の方法です。そうでなければ、私は推測するでしょう。 – adamjmarkham

関連する問題