前提・実現したいこと
スレッドを使って、キャラクター同士で戦闘を行い、攻撃を仕掛ける度に攻撃を受けた側のHPをー1する。
どちらかのキャラクターのHPが0になったらその時点で処理をやめる。
HPが0になったキャラクターは攻撃してはならず、攻撃側もHP0のキャラを攻撃できない。
発生している問題・エラーメッセージ
どちらかのHPが0になっても、1回だけ死んだはずのキャラが攻撃してしまう。
実際の実行結果
Rock attacked Jay , Rock:10 , Jay:9
Rock attacked Jay , Rock:10 , Jay:8
Jay attacked Rock , Jay:8 , Rock:9
Rock attacked Jay , Rock:9 , Jay:7
Jay attacked Rock , Jay:7 , Rock:8
Rock attacked Jay , Rock:7 , Jay:6
Jay attacked Rock , Jay:6 , Rock:7
Jay attacked Rock , Jay:6 , Rock:6
Rock attacked Jay , Rock:6 , Jay:5
Rock attacked Jay , Rock:6 , Jay:4
Rock attacked Jay , Rock:6 , Jay:3
Jay attacked Rock , Jay:3 , Rock:5
Rock attacked Jay , Rock:5 , Jay:2
Jay attacked Rock , Jay:2 , Rock:4
Rock attacked Jay , Rock:4 , Jay:1
Jay attacked Rock , Jay:1 , Rock:3
Jay attacked Rock , Jay:1 , Rock:2
Rock attacked Jay , Rock:2 , Jay:0
Jay attacked Rock , Jay:0 , Rock:1
↑でJayは死んでいるはずなのに攻撃している。
Jaylost.
該当のソースコード
Java
class Fight{ public static void main(String args[]) { RPGCharacter c1 = null,c2 = null; c1 = new RPGCharacter("Jay",10); c2 = new RPGCharacter("Rock",10); c1.setTarget(c2); c2.setTarget(c1); c1.start(); c2.start(); } } class RPGCharacter extends Thread{ String name; int hp; RPGCharacter target; Object lock = new Object(); RPGCharacter(String name,int hp){ this.name = name; this.hp = hp; } void setTarget(RPGCharacter target) {this.target = target;} RPGCharacter getTarget(){synchronized(lock) {return target;}} void attack() { synchronized(lock) { while(hp>0&&target.hp>0) { try {Thread.sleep((int)(10*Math.random()));} catch(InterruptedException ie) {} if(target.hp>0)target.hp--; System.out.println(name + " attacked " + target.name + " , " + name + ":" + hp + " , " + target.name + ":" + target.hp); } if(hp<=0) { System.out.println(name + "lost."); } } } public void run() { attack(); } }
試したこと
synchronizedの書き方をいろいろ試したのですがどうもうまくいきません!c1とc2、同時に処理が行われているから、HPが0になった判定while(hp>0&&target.hp>0)を受ける前に攻撃の処理をしてしまうっていうことは何となくわかるのですが、、
同期処理についての理解が足りないのでしょうか?
補足情報(FW/ツールのバージョンなど)
Java初心者なので、質問内容等で不快にさせてしまったら申し訳ありません!
まだ回答がついていません
会員登録して回答してみよう