定番の占いアプリをJavaで作成してみよう!seedを使ってその日の運勢は一定になる仕組みを入れていく。
実行例
1.実行時引数を入れないと「あなたの」と表示される
$ java Fortune
あなたの 2021/11/4 の運勢は大吉です!
2.実行時引数に名前を入れると「誰々さんの」という表示になる
$ java Fortune 山田
山田さんの 2021/11/4 の運勢は中吉です!
仕様
○その名前に対する、その日の運勢は一定(日付が変わると運勢も変わる) ○これはハッピー占いである。運勢の出る確率は 大吉:60%,中吉:30%,吉:7%,凶:3% とする
Let’s チャレンジ
腕に自身のある人は自力でやってみよう。
作成のヒント
○実行時引数の受け取りはmain(String[] args)と記述した場合のargs[0]で取得できる。なので引数が来ていた場合はその名前、そうでなければ「あなた」にする処理は以下のような感じになる。
String name=args.length == 0 ? "あなた":args[0]+"さん";
○実行日時を調べるのはいつものCalendarクラスを使うとよい。
Calendar today=Calendar.getInstance();
int year=today.get(Calendar.YEAR);
int month=today.get(Calendar.MONTH);
int day=today.get(Calendar.DATE);
○名前と日付でseed値を作成するメソッドを作成してみよう。 ここではChar型がintの性質も持っていることを利用している。
static int calcSeed(String name,int year,int month,int day){
int seed = year+month+day;
for (int i = 0; i < name.length(); i++) {
seed += name.charAt(i);
}
return seed;
}
○seed値を利用し、確率に基づいた運勢を返却するメソッドを作成しよう。 今回はMap<String,Integer>を使って実装した。
static String getFortune(int seed){
String fortune=null;
Random rand=new Random(seed);
Map<String,Integer> data=new LinkedHashMap<>(){
{
put("大吉",60);
put("中吉",30);
put("吉",7);
put("凶",3);
}
};
int n=rand.nextInt(100);
for(String key:data.keySet()){
if(n-data.get(key) < 0){
fortune=key;
break;
}
n-=data.get(key);
}
return fortune;
}
補足
■LinkedHashMapは格納順を保持する。こうすれば大吉->中吉->吉->凶という格納順を保持できる。
■匿名クラスとイニシャライザの仕組みを使ってMapに初期値を入れている。ここでは細かい説明は省くが、ListやMapはこの仕組で初期値をいれることができるのを知っておくと便利だ。意味的には以下と同意
Map<String,Integer> data=new LinkedHashMap<>();
data.put("大吉",60);
data.put("中吉",30);
data.put("吉",7);
data.put("凶",3);
■確率に基づいて運勢を決める処理は色々あるが、今回はforと引き算を利用している。0-99の100種類の乱数のうち0-59の60種類の値が出た場合は大吉となることを頭の中で確認してもらいたい。
全ソースコード
import java.util.*;
public class Fortune {
public static void main(String[] args) {
String name=args.length == 0 ? "あなた":args[0]+"さん";
Calendar today=Calendar.getInstance();
int year=today.get(Calendar.YEAR);
int month=today.get(Calendar.MONTH);
int day=today.get(Calendar.DATE);
int seed=calcSeed(name,year,month,day);
String fortune=getFortune(seed);
System.out.printf("%sの %d/%d/%d の運勢は%sです!%n",name,year,month+1,day,fortune);
}
static int calcSeed(String name,int year,int month,int day){
int seed = year+month+day;
for (int i = 0; i < name.length(); i++) {
seed += name.charAt(i);
}
return seed;
}
static String getFortune(int seed){
String fortune=null;
Random rand=new Random(seed);
Map<String,Integer> data=new LinkedHashMap<>(){
{
put("大吉",60);
put("中吉",30);
put("吉",7);
put("凶",3);
}
};
int n=rand.nextInt(100);
for(String key:data.keySet()){
if(n-data.get(key) < 0){
fortune=key;
break;
}
n-=data.get(key);
}
return fortune;
}
}
コメント