2011-06-24 69 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