質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

2回答

2160閲覧

Javaでタイマーを実施する方法(遅延実行)

anpan___

総合スコア28

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2020/01/24 00:22

編集2020/01/24 01:19

現在課題にてJavaでオセロを作成しております。
最終的な課題としては、コンピューター同士を戦わせることです。
またその際に条件があり、
1・指定の動作で作る。(コンピューターの強さをある程度強くするため)
2・CSVファイルで読み取った、盤面に格納されている優先順位から駒を置いていけるように。

3・今後先読みの処理を加えるため、コンピューターが配置する直前に2秒の空き時間を作る。

オセロ自体の処理・コンピュターの処理は完了しており現在は3の動作を作成しております。
こちらでは失敗したコードではなく、現状タイマーを実施していないコードを作成しています。
実際に行ったことは、
(//盤面描写)の直前に2秒スリープするコードを実行しました。そのコードは二つ目の引用に載せています。

結果として、全てのコンピューターの処理が終わった後に、コンピューターのやり取りの数だけ、遅れて”テスト”と表示される状況に陥ってしまいました。

While文の中で、スリープを使うことはできないのでしょうか…?
ご教授いただければ幸いです。

java

1public static void main(String[] args) throws IOException { 2 Timer time = new Timer(); 3 String[] kazu = { "1", "2", "3", "4", "5", "6", "7", "8" }; 4 String[] color = { "", "●", "◯", "置ける場所(?)" }; 5 int[] status = new int[4];//盤面の状況を格納 6 int col, row = 0;//コマを置く縦位置、横位置 7 int failed_cnt = 0; //駒をおけなかったらカウント 8 p1 = new Player('c', 1);//プレイヤー1 黒 9 p2 = new Player('c', 2);//プレイヤー1 白 10 pw = p1;//作業用 11 while (true) {//ゲームメインループ 12 =============中略=============== 13     配列の初期化おける位置の初期化 14    置ける場所チェック 15 コマが置かれていない場所をチェック 16 17 if (Code.check_change(board, i, j, pw.color, "check")) { 18 board[i][j] = 3;//置ける時statusを3に 19 } 20 //盤面描画 21 time.schedule(new task(),2000); 22 Code.print(kazu, board, rank);//Code:コードをいくつか格納したクラス 23 24 //盤面のチェックその2 25 for (int i = 0; i < board.length; i++) { 26 for (int j = 0; j < board[i].length; j++) { 27 status[board[i][j]]++; 28 } 29 } 30 =============中略=============== 31(ゲームを続行できるかのチェック)ex)置ける位置がない、二人とも置けなかったらゲーム終了 32 33 for (int i = 1; i < status.length; i++) {//盤面の状態を表示 34 System.out.println(color[i] + ":" + status[i] + " "); 35 } 36 System.out.println("------------------------"); 37 System.out.println(color[pw.color] + "のターン" + " "); 38 int[] point = pw.getPoint(); 39 col = point[0]; 40 row = point[1]; 41 if (board[col][row] != 3) { 42 System.out.println("指定された位置にはコマを置けません。"); 43 System.out.println("置ける位置を指定して下さい。"); 44 System.out.println("------------------------"); 45 continue; 46 } else {//コマを置き、ひっくり返す 47 board[col][row] = pw.color; 48 Code.check_change(board, col, row, pw.color, "change"); 49 System.out.println("------------------------"); 50 } 51 Player.changePlayer();//プレイヤー交代 52 } //mainループ 53 54 =============中略===============(勝敗判定) 55 } 56 }

Java

1import java.util.TimerTask; 2 3public class task extends TimerTask { 4 public void run(){ 5 try { 6 Thread.sleep(1000); 7 System.out.println("テスト"); 8 9 }catch(Exception ex) { 10 ex.printStackTrace(); 11 } 12 } 13}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/01/24 01:04

ご提示のコードがtaskクラスを使っていない(どのように使っているか分からない)ので何とも言えないのですが、単純にThread.sleep(2000); で2秒待機させるのではダメなのでしょうか。
anpan___

2020/01/24 01:23

修正依頼ありがとうございます! 実行しているタイミングを追加させていただきました…???? 今後2秒間の停止の中で、 ・置く事ができる位置に配置して先読み(別配列で保存)、そして2秒たった中で見つける事ができた、最善のマスに駒を配置する。 という処理を作成予定です! その処理のため、taskを作成し、その中に処理を打ち込む必要があると感じております。 上記の理由から、別のクラスを用意しています!
dodox86

2020/01/24 01:39

別で動かす先読み処理は最大で2秒待機し、もし2秒未満で先読み完了すればすぐ復帰、みたいなものであればスレッドや非同期処理の意義はあると思います。クラスの設計もそうですが、「同期」についても意識して調べてみると良いと思います。
jimbe

2020/01/24 10:14

オセロの最善手を探すのに2秒掛かるものなのでしょうか. もし最悪の場合でも2秒掛からなければ, 2秒を計る処理は不要ということになります. 最善手を探すアルゴリズムがまだ決まっておらず, どれくらい時間が掛かるか分からないのであれば, 今のところは dodox86 さんの言われたように sleep のみとしておいたほうが良いのではないでしょうか.
anpan___

2020/01/27 00:07

dodox86様、jimbe様 ご指摘ありがとうございます。また、ご返信遅れてしまい誠に申し訳ありません…。 同期の件かしこまりました。一度勉強し、実際にどのように使えるものなの考えてみることにいたします! また、現状はスリープのみにしておき、先に最善手を探すクーどの方を作成させていただくようにしたいとも思います。 ご指摘ありがとうございました!
guest

回答2

0

taskクラスのrunメソッドをどのように呼び出しているのかが気になります
task.run()の様に呼び出していた場合は良いですが
(new Thread(task)).start()の様な呼び出しの場合、別のスレッドの動作となりメインスレッドの動作が止まることはありません

投稿2020/01/24 00:59

編集2020/01/24 01:08
Sepi

総合スコア36

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anpan___

2020/01/24 01:10

ご回答ありがとうございます!実際に呼び出していたコードは後者のものでした…! 冒頭でTimer time = new Timer();をし、 Code.print();の直前に time.schedule(new task(), 1000); を入れてしまっておりました???? いいど呼び出し方を変えてみます!
guest

0

先読みをスレッドで行う

3・今後先読みの処理を加えるため、コンピューターが配置する直前に2秒の空き時間を作る。

スレッドで先読みを実行するほうが自然ではないでしょうか。How to timeout a thread

  • 2秒以内に先読みの結果が得られれば利用する
  • 2秒待っても先読みの結果が返らなければスレッドを破棄する

先読処理の実装

自分で先読処理を実装するとしたらどうするか。質問に直接答えようとしない興味本位のコードです。

  • ExecutorServiceフレームワークを使用する
  • 先読処理はスレッドで実装する(Future,Callableを使用する)
  • タイムアウト時間を指定する
  • 先読処理がタイムアウト時間を超過するならキャンセルする

Java

1import java.util.concurrent.CancellationException; 2import java.util.concurrent.ExecutionException; 3import java.util.concurrent.Executors; 4import java.util.concurrent.Future; 5import java.util.concurrent.ScheduledExecutorService; 6import java.util.concurrent.TimeUnit; 7import java.util.concurrent.TimeoutException; 8 9 static String wait4LookaheadSearch(final int timeout) { 10 11 String result = "none."; 12 ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 13 14 try { 15 // 先読み処理を実行する。 16 final Future<String> handler = executor.submit( 17 () -> { 18 System.out.println("look-ahead search ... "); 19 try { 20 Thread.sleep((int) (Math.random() * timeout * 2)); 21 } catch (InterruptedException e) { 22 throw e; 23 } 24 if (Thread.interrupted()) throw new InterruptedException(); 25 return "the best hand."; // 先読み結果を返す。 26 }); 27 28 try { // 最適解が見つかるか、タイムアウトするまで待つ。 29 result = handler.get(timeout, TimeUnit.MILLISECONDS); 30 } catch (TimeoutException e) { // タイムアウトした 31 if (!handler.isDone()) { 32 handler.cancel(true); // キャンセルする(強制割り込みをかける) 33 } 34 result = "timeout."; 35 } catch (ExecutionException | InterruptedException | CancellationException e) { 36 result = "failed."; // 実行失敗 37 } 38 } finally { 39 executor.shutdownNow(); 40 } 41 return result; 42 }

使い方は、"main"スレッドを2秒スリープする代わりにwait4LookaheadSearch(2000);とします。Timerを使うとmain()が複雑になりバグの多いコードになると思います。とはいえ、このコードはあくまでも参考にすぎません。バグがあるかもしれないし、他の実装方法も考えられるでしょう。

投稿2020/01/28 09:48

編集2020/01/29 09:47
xebme

総合スコア1081

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問