転職を繰り返したサラリーマンの多趣味ブログ

30才未経験でSEに転職した人の多趣味ブログ

【モンスターハンターワールド】モンハン初心者がモンスターハンターワールドを始めてみた。

これまでこのブログは、プログラミングとゲーム作りについて書いてきた。ほぼ、自分のための勉強ブログだ。
で、今はUnityを使ったゲーム作りをメインでやってるが、面白いゲームを作るには、面白いゲームをやらなければいけない。もちろん、これまでもゲームはやっているが、ただ何となくやっていただけだった。
だから、色々意識してゲームをやるために、ゲームのプレイ記録をつけることにした。
それの第一回目として、最近拡張パックが発売された「モンスターハンターワールド」を選んだ。

f:id:uuc1h:20190916225400j:plain
ちなみに、これまでモンハンはやったことなくて、このモンスターハンターワールドが初モンハンだ。ということで、今後のゲーム作りに役立てるように、プレイ日記をつけていく。

キャラク

まずは、キャラクリ。色々細かく選べるが、性別まで選べる。性別によって、装備できる武器が違うようだが、ここは女性を選択。最終的にはこんな感じになりました。

f:id:uuc1h:20190916225556j:plain

いざ、本編へ

続いて、さっそく本編へ。主人公を含めた調査団が船でとある島へ向かうシーンから始まる。そこで、よくティザー映像で見る女の子が出てきた。

f:id:uuc1h:20190916225955j:plain

しかしそこで、波が大きく荒れて、船が沈没する。海からいきなり山がでてきたと思ったら、どうやらモンスターだったみたい。

f:id:uuc1h:20190916230209j:plain

なんとか目的の島にたどり着き、本来船が到着するはずだった調査拠点へ向かう。

f:id:uuc1h:20190916230437j:plain

色々あるも、無事に調査拠点アステラに到着。ここまでは、結構あっさりつけた。

f:id:uuc1h:20190916230559j:plain

そして、調査団の総司令に会い、この調査の目的が古龍渡りを解明することだという。
この古龍渡りとは、古龍が現大陸から新大陸へ向けて、大移動する現象を指すらしい。

f:id:uuc1h:20190916230929j:plain

このゾラ・マグダラオスが、さっき船を沈没させたモンスターのことなのかな?
ちょっとまだそこらへんは分からないが、さっそく主人公に対してクエストが与えられた。

f:id:uuc1h:20190916231126j:plain

うーん、ジャグラスって何や?何も分からんけど、まずは装備をしろということで、装備を行うマイハウスへ。

マイハウスでの装備

f:id:uuc1h:20190916231840j:plain

武器は全部で14種類。選ぶ武器によって、アクションが異なるとのこと。
防具は全5つのパーツで構成されており、装備スキルもある。これら組み合わせを、マイセットとして登録しておくことも可。

f:id:uuc1h:20190916232353j:plain

武器を選ぶときに便利だなと思ったのが、その武器でできるプレビューが動画で見れることと、初心者おすすめ度が見れること。このおすすめ度、自分みたいに何も分からない人からすると、武器を選ぶときの大きな指針になる。

f:id:uuc1h:20190916232536j:plain

あと、武器を変更する際、こうやって武器の各ステータスが比較できるのもいい。

f:id:uuc1h:20190916232824j:plain

で、防具のスキルもここで確認できる。
次に、選んだ武器の練習の実施。

f:id:uuc1h:20190916233905p:plain

武器のアクションって、こんなにあるのか。。これ、連携も含め操作を覚えて、実際の戦闘でやろうと思うとかなり大変な気が。
今日は、この練習をちょっとやったとこで終わりです。次回は、実際のクエストをできるかな。




MacBook Pro(13-inch, Mid 2010)をSSDに換装した。

少し前に、MacBook Proのメモリーを16GBに増設し、多少動作に改善が見られた。ただ、メモリーを増やしたところで、「本体の起動が遅い」、「アプリケーションの起動が遅い」、「Unity、Visual Studioが重い」といった事象は解消されなかった。

uuc1h.hatenablog.jpやはり、SSDの換装が必要だなと思い、Amazon Prime Dayを利用し、SSDを購入した。事前に色々調べていて、SSD換装に必要な物は、ここで一気に購入した。

 ちなみに、MacBook Proの裏ふたを開ける精密ドライバーはすでに持っていたので、ここでは購入していない。

で、実際のSSD換装手順は、以下の手順通りそのままにうまくいった。本当に詳しく、分かりやすく手順を載せてくれているので、マジでありがたいです。
https://rikei-danshi.work/entry/2018-08-10-ssd

1点だけ注意が必要なのが、MacBook Pro 13-inchは、macOS mojavaには非対応で、macOS High Sierraをインストールする必要がある。
ただApp Storeを普通に検索してもmacOS High Sierraが検索でヒットしない。
いろいろ調べたら、ここからmacOS High Sierraインストーラーをゲットできた。
https://support.apple.com/ja-jp/HT208969

f:id:uuc1h:20190728092455p:plain

上記画像の「こちらのリンク」をクリックすると、App Storeが開き、macOS High Sierraをダウンロードできた。あとは、手順通りにスムーズにできた。

で、無事にSSDに換装でき、MacBook Proを起動すると、たしかに早い。これまでの起動時間の半分くらいになっていると思う。あと、アプリケーションの起動も早くなっている。
「おーこれはSSDに換装した甲斐があったなー」とUnity、Visual Studioを起動し、いろいろ使っていくと、各アプリケーションが重い事象は改善されていない。
また、アプリケーションの実行時に、本体が熱を持ち、ファンが凄まじく回転する事象もそのままである。
いくらSSDに換装したといえ、CPUがCore2Duoではキツイのか。。。
こればっかりは仕方ないような気がするので、MacBook Proの改造はここまでとします。

スペックだけみると、メモリー16GB、SSD500GBと高スペックになったな。しかも、金額的にはちょうど2万円くらいでできるし、手順もそれほど複雑ではないのでかなりオススメできる作業だ。
けど、最新のmacOSに対応していないし、CPUが非力なままなので、早く新しいパソコン買いたいなー。

もう自分も年なんだなと感じた今日この頃。

f:id:uuc1h:20190724185841j:plain

よくCMで、「日本人の8割は歯周病にかかっている」とかって見ても、「ふーん」ぐらいにしか感じたことがなかったし、むしろ「ふーん」とも思わないことが多かった。
だがしかし、最近銀歯が取れたので、かれこれ4年振りぐらいに歯医者に行ったら、かなりショックな診断が。。

 

「かなり進行している虫歯があります。あと、歯周病が進んでいて、このままいくと歯がぐらついてきます。」

「えっ、治るんですよね?」

「治療は行えますが、これ以上病状が進まないようにする現状維持しかできません。」

「えっ、じゃあもう歯が抜けちゃいます?」

「いえ、今から治療すればこの先も自分の歯は守れますよ」

あぶねえ、ギリセーフ。。ということで、しばらく歯医者に通うハメになりました。
けど、自分は、歯ブラシだけでなく、デンタルフロスも毎日使って、結構気を使ってた方なんだけどなぁ。タバコも吸わないし、歯周病なんて自分には全くの無関係だと思ってただけに、かなり落ち込む。

まぁ、このタイミングで見つかったことを幸運として、これからは定期的に歯医者に通うことにします。

今日は久しぶりにブログらしいブログを書こうと思う。

継続は力なりとはよく言うけども、それは確かに本当なんじゃないかという気がしてきた。
このブログ、立ち上げてから2年以上たっている。当初は、ブログでお小遣いを稼げたらなーと思っていたが、全く稼げない。そもそもアクセスが無いのだ。
けど、考えてみたら当たり前で、何の特徴も無いただのサラリーマンのブログなんか、誰も読もうと思わない。だから、最近はアクセス数はそんなに気にしないで、自分のアウトプット用として、このブログを使っている。例えば、こんな風にだ。

uuc1h.hatenablog.jp

こういうことを続けていたら、1日10アクセスもなかったのが、1日50アクセスぐらいに増えてきた。1ヶ月で1000アクセスを超えるまでになってきた。
なんどもなんどもブログやめようとしたけど、このまま続けてみるか。 

 

【技術書メモ】C#プログラミングのイディオム / 定石&パターン⑧

今回は、日付、時刻の操作方法。

DateTime構造体

DateTime構造体のインスタンス生成の主な方法と、よく使われるTodayプロパティとNowプロパティ。

// インスタンス生成
var dt1 = new DateTime(2016, 2, 15);
var dt2 = new DateTime(2016, 2, 15, 8, 45, 20);

// TodayとNowプロパティ
var today = DateTime.Today;
var now = DateTime.Now;


また、DateTime構造体には、年、月、日など、様々な日付および時刻の情報を、プロパティから参照することができる。
※ここでは割愛。


指定した日付の曜日の求め方。

var today = DateTime.Today;
DayOfWeek dayOfWeek = today.DayOfWeek;
if(dayOfWeek == DayOfWeek.Sunday)

// DayOfWeekプロパティの型はDayOfWeek列挙型
public enum DayOfWeek {
    Sunday = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6


DayTime構造体を使用すれば、閏年の判定も可能。

var isLeapYear = DateTime.IsLeapYear(2016);


日付形式のもう字列をDateTimeオブジェクトに変換する方法。

DateTime dt1;
if(DateTime.TryParse("2017/6/21", out dt1))
    // 2017/06/21 0:00:00
    Console.WriteLine(dt1);
DateTime dt2;
if(DateTime.TryParse("2017/6/21 10:41:38", out dt2))
    // 2017/06/21 10:41:38
    Console.WriteLine(dt2);

日時のフォーマット

日時を文字列に変換するには、ToStringメソッドを使用する。
ToStringの引数に、あらゆる書式を指定すると、結果の値も変わってくる。

var date = new DateTime(2016, 4, 7, 21, 6, 47);
var s1 = date.ToString("d"); // 2016/04/07


日付を和暦で表示するには、DateTimeクラスを使用する。

var date = new DateTime(2016, 8, 15);
var culture = new CultureInfo("ja-JP");
culture.DateTimeFormat.Calendar = new JapaneseCalendar();
var str = date.ToString("ggyy年M月d日", culture);


指定した日付の元号を得るには、DateTimeFormatInfoクラスのGetEraNameメソッドを使用する。

var date = new DateTime(1995, 8, 24);
var culture = new CultureInfo("ja-JP");
culture.DateTimeFormat.Calendar = new JapaneseCalendar();
// 元号コードの取得
var era = culture.DateTimeFormat.Calendar.GetEra(date);
// 元号コードから元号名を得る
var eraName = culture.DateTimeFormat.GetEraName(era);


指定した日付の曜日を得るには、DateTimeFormatInfoクラスのGetDayNameメソッドを使用する。

var date = new DateTime(1998, 6, 25);
var culture = new CultureInfo("ja-JP");
culture.DateTimeFormat.Calendar = new JapaneseCalendar();
// 曜日の取得
var dayOfWeek = culture.DateTimeFormat.GetDayName(date.DayOfWeek);

DateTimeの比較

日時を比較するには、比較演算子をそのまま利用できる。

var dt1 = new DateTime(2006, 10, 18, 1, 30, 21);
var dt2 = new DateTime(2006, 11, 2, 18, 5, 28);
if (dt1 < dt2)
else if (dt1 == dt2)


時刻情報を含まない日付だけを比較する場合は、Dateプロパティを使う。

var dt1 = new DateTime(2001, 10, 25, 1, 30, 21);
var dt2 = new DateTime(2001, 10, 25, 18, 5, 28);
if (dt1.Date < dt2.Date)
else if (dt1.Date == dt2.Date)

日時の計算

指定した時分秒後を求めるには、TimeSpan構造体を使用する。

var now = DateTime.Now;
// TimeSpanオブジェクトを加える
var future = now + now TimeSpan(1, 30, 0);


n日後、n日前の日付を求めるには、AddYears、AddMonthsメソッドを利用する。

var date = new DateTime(2009, 10, 22);
var future = date.AddYears(2).AddMonths(5);


2つの日時の差を求める。

var date1 = new DateTime(2009, 10, 22, 1, 30, 20);
var date2 = new DateTime(2009, 10, 22, 2, 40, 56);
TimeSpan diff = date2 - date1;
Console.WriteLine("差は、{0}日間{1}時間{2}分{3}秒です", diff.Days, diff.Hours, diff.Minutes, diff.Seconds);
Console.WriteLine("トータルで{0}秒です", diff.TotalSeconds);


2つの日付の日数差を求める。

var date1 = new DateTime(2009, 10, 22, 1, 30, 20);
var date2 = new DateTime(2009, 10, 22, 2, 40, 56);
TimeSpan diff = date2.Date - date1.Date;
Console.WriteLine("{0}日間", diff.Days);


DaysInMonth静的メソッドを使えば、月末日を求めれる。

var today = DateTime.Today;
int day = DateTime.DaysInMonth(today.Year, today.Month);
var endOfMonth = new DateTime(today.Year, today.Month, day);


DayOfYearプロパティを使って、1月1日からの通算日を求める。

var today = DateTime.Today;
int dayOfYear = today.DayOfYear;

【技術書メモ】C#プログラミングのイディオム / 定石&パターン⑦

今回はディクショナリの操作について。ディクショナリと聞くと馴染みがないが、JavaでいうMapと認識している。

ディクショナリの基本操作

ディクショナリの初期化。

var flowerDict = new Dictionary<string, int>() {
    {"sunflower", 400},
    {"pansy", 300},
};


なお、ディクショナリにはオブジェクトも値に格納できる。

var employeeDict = new Dictionary<int, Employee> {
    {100, new Employee(100, "やまだ") },
};


では、続いて各操作を確認していく。
まずは、要素の追加から。

flowerDict["violet"] = 600;

// Addメソッドを使う場合
flowerDict.Add("violet", 600);


要素を取り出す。

int price = flowerDict["rose"];


指定したキーにディクショナリが存在しない場合は、例外が発生してしまう。
そのため、ディクショナリにキーが存在しているか調べることができる。

var key = "pansy";
if (flowerDict.ContainsKey(key)) {
}


ディクショナリから要素を削除する。

var result = flowerDict.Remove("pansy");


ディクショナリからすべての要素を取り出す。
foreach文を使うことになるが、foreachで取り出せる要素の型は、KeyValuePair型。
Keyプロパティでキーの値、Valueプロパティで対応する値を参照する。

foreach (var item in flowerDict)
    Console.WriteLine("{0} = {1}", item.Key, item.Value);


では、ディクショナリからすべてのキーを取り出す方法をみてみる。

foreach (var key in flowerDict.Keys)

ディクショナリの応用

配列やリストをディクショナリに変換する。

var employeeDict = employees.ToDictionary(emp => emp.Code);


ディクショナリから別のディクショナリを作成する。
ディクショナリからある条件に一致したものだけを抜き出し、新たにディクショナリを生成するなどの場合に用いられる。

var newDict = flowerDict.Where(x => x.Value >= 400).ToDictionary(flower => flower.Key, flower => flower.Value);


カスタマクラスをキーにする。
文字列や数値ではなく、独自に作成したカスタムクラスも、ディクショナリーのキーにできる。
ただ、これには一つだけ注意が必要で、キーに使用するカスタムクラスに、EqualsメソッドとGetHashCodeメソッドをオーバーライドする必要がある。

public int Day { get; private set; }

public int Month { get; private set; }

public MonthDay(int month, int day) {
    this.Month = month;
    this.Day = day;
}

public override bool Equals(object obj) {

    var other = obj as MonthDay;
    if (other == null)
        throw new ArgumentException();
    return this.Day == other.Day && this.Month == other.Month;

}

public override int GetHashCode() {
    return Month.GetHashCode() * 31 + Day.GetHashCode();
}
public static void Main(string[] args)
{

    var dict = new Dictionary<MonthDay, string> {
        {new MonthDay(3, 5), "珊瑚の日" },
        {new MonthDay(8, 4), "箸の日" },
        {new MonthDay(10, 3), "登山の日" },
    };

    var md = new MonthDay(8, 4);
    var s = dict[md];
    Console.WriteLine(s);
}


ディクショナリを使う際、キーがディクショナリに格納されていることが重要で、その値を利用しないケースがある。
こういった場合は、HashSetクラスを使用する。

var hash = new HashSet<string>();
hash.Add("string");
hash.OrderBy();


ディクショナリは、キーの重複を許していない。そのため、同一キーで複数のオブジェクトを関連づけることができない。
こういう場合は、値をリスト型にしておく。

var dict = new Dictionary<string, List<string>() {
    { "PC", new List<string> {"パーソナルコンピュータ", "プログラムカウンタ",}},
}

【技術書メモ】C#プログラミングのイディオム / 定石&パターン⑥

今回は、配列とListの操作です。
配列とListは似たところがあるけど、自分はほぼListしか使わないかも。配列の使い所がわからない。
この章ではLINQのさらに詳しい使い方も説明してくれるらしいので、頑張ります。

要素の設定

配列あるいは、Listを同じ値で埋める。

// List<T>(要素数:20個)の値を-1で埋める
var numbers = Enumerable.Repeat(-1, 20).ToList();

// 配列(要素数:12個)の値をunknownで埋める
var strings =  Enumerable.Repeat("(unknown)", 12).ToArray();


配列あるいは、Listに連続した値を設定する。

// 配列に1〜20の値を設定
var array = Enumerable.Range(1, 20).ToArray();

コレクションの集計

平均値の求め方。

var numbers = new List<int>{9, 7, 5, 4, 2, 5, 4, 0, 4, 1, 0, 4};
var average = numbers.Average();

// 合計の求め方
var sum = numbers.Sum();


最小値、最大値の求め方。

var numbers = new List<int>{9, 7, 5, 4, 2, 5, 4, 0, 4, 1, 0, 4};
var min = numbers.Where(n => n > 0).Min();
var max = numbers.Where(n => n > 0).Max();


条件に一致する要素をカウントする。

var count = numbers.Count(n => n == 0);

コレクションの判定

条件に一致する要素があるかどうか調べる。
Anyメソッドは、条件に一致する要素が見つかった時点で要素の取得を中止する。

bool exists = numbers.Any(n => n % 7 == 0);


コレクション内のすべての要素が条件を満たしているかどうかを調べる。

bool isAllPositive = numbers.All(n => n > 0);


2つのコレクションの要素が等しいか調べる。

bool equal = numbers1.SequenceEqual(numbers2);

単一の要素の取得

条件に一致する最初、または最後の要素を取得する。

var word = words.FirstOrDefault(x => x.Length == 4);
var word = words.LastOrDefault(x => x.Length == 4);


条件に一致する最初、または最後のインデックスを求める。

var index = numbers.FindIndex(n => n < 0);
var index = numbers.FindLastIndex(n => n < 0);

複数の要素の取得

条件を満たす要素をn個取り出す。

var results = numbers.Where(n => n > 0).Take(5);


コレクションの中から、条件を満たしている間だけ要素を取り出す。
例として、400, 281, 389, 637, 411というリストがあった場合、600以下という条件をつけたら、先頭の400、281、389だけ取れるというもの。

var selected = books.TakeWhile(x => x.Price < 600);


では逆に、条件を満たしている間だけ要素を読み飛ばすには、SkipWhile演算子を使う。

var selected = numbers.SkipWhile(n => n >= 0).ToList();

その他の処理

コレクションから別のコレクションを生成する。
基本的には、ToArray()、ToList()メソッドを使用する。

var words = new List<string>{"Microsoft", "Apple", "Google", "Oracle", };
var lowers = words.Select(name => name.ToLower()).ToArray();


重複を排除する。

var result = numbers.Distinct();


コレクションを並び替える。

// 昇順にソート
var sorteBooks = books.OrderBy(x => x.Price);

// 降順にソート
var sortedBooks = books.OrderByDescending(x => x.Price);


2つのコレクションを連結する。

var allfiles = files1.Concat(file2);