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

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

【Unity】unity1weekで作ったゲームを改良して、Google Play Storeへリリースした

約2カ月かけて、unity1weekで作ったゲームを改良してAndroidアプリを開発した。
そのアプリがこれ。

f:id:uuc1h:20210404104801p:plain

play.google.com

いわゆるウォーリーを探せ的なゲームです。全50問作ったのでボリュームは十分で、問題が進むと高難易度の問題もでてきます。
サクッとできるゲームなので、ぜひ遊んでみてください。

【Unity】Google Play Consoleにaabファイルをリリースしたらエラーになった

タイトルの通り、Google Play Consoleにaabファイルをリリースしたら、以下エラーメッセージが表示された。

f:id:uuc1h:20210404103859p:plain

リリース時には、いつも何らかのエラーが出てしまうので対応方法をメモする。
調べてみたら、対応方法はかなり簡単だった。
UnityのProject Settings / Other Settings / Target ArchitecturesでARM64にチェックを入れること。

f:id:uuc1h:20210404104345p:plain

これで無事にリリースできた!

【NBA】明日はオールスターゲームだから、お気に入りのオールスターゲームについて語りたい

タイトルそのまんまです。日本時間の8日10:00に、オールスターゲームが行われる。近年のオールスターゲームは、各チームのキャプテンによるドラフト形式でチームが決定する。今年はチームレブロンvsチームデュラント。ドラフト形式になってから、レブロンはずっとキャプテンを就任しているのも凄い。ちなみにキャプテンは、ファン投票の最多得票者が選ばれるから、レブロンはずっと人気があるってことになる。
レブロンは今36才やけど、アスリートで36才といえば人によっては引退する年だし、そもそも身体能力は確実に落ちる。しかし素人目には、レブロンの身体能力は一切落ちていないように見える。普通は落ちるはずのジャンプ力も全く落ちていないから、今でも凄まじいダンクを決めるし、ヒート時代にスパーズ相手にみせた鬼の形相のブロックも今でもする。そこに、今のレブロンは経験が加わっているから、必要な時以外はパワーを抑えていて、ここぞというときに自分が得点をとりにいく。いわゆる、試合全体を見ているし、何ならシーズンを通して優勝までを見据えてコントロールしているから、本当に史上最高のバスケットプレイヤーなんかじゃないかと思えてくる。

序盤でレブロンについて語ってしまったが、本当に語りたいことはお気に入りのオールスターゲームのことだ。自分が一番好きなオールスターゲームは、やはり初めてみたオールスターゲームだ。それは2005年にデンバーで行われた、アレン・アイバーソンがMVPをとったオールスターゲームだ。
まず何がいいって、入場が死ぬほどかっこいい。。2005年は、ベンチメンバーも一人ずつ入場するスタイルだった。そこで各選手が思い思いのポーズをとるのだが、アレン・アイバーソンの入場は格別だ。

実際の試合内容もこれぞオールスターゲームという内容。序盤はディフェンスゆるめで、各選手がダンクを派手に決めたり、シャックがポイントガードをやったりと。で、後半になると真剣モードになる。豪華メンバー同士の真剣勝負がオールスターゲームの醍醐味だと個人的に思う。真剣勝負といえば、2007年にラスベガスで行われたオールスターゲームで、コービーがジョージョンソンとの1on1でぬきさり、ダンクを決めたのも思い出す。

けど、2014年ごろから真剣勝負が見られなくなった。常にディフェンスに手をぬき、3ポイントをうつだけのつまらないものになってしまった。2017年なんて200点近く点が入ったんだから確実にディフェンスしていない。この状態をファンもリーグも問題視し、ついに昨年改革が行われた。勝利チームは、施設に寄付ができるという特典がついて、両チームがきちんと勝負する目的を作ったのだ。これが功をそうして、終盤だけでなく終始真剣勝負を見ることができた。だから、2020年のオールスターゲームもお気に入りだ。今年のオールスターゲームのルールはまだ見ていないが、今年もスター選手たちの真剣勝負を見たい。

言葉が出てこないときってありますよね?

最近、記憶力の低下に悩んでいる。言葉が本当に出てこない。結婚して3年たつが、妻とは「アレ」で意思疎通ができるようになってきてしまった。これも、言葉が出てこない原因なのではないかと思う。
これはいかんと思い、記憶力の強化を目的とした日記をつけ始めた。ブログやnoteではなく、手書きの日記だ。Twitterで、1日の振り返りがいいというつぶやきを見つけたのが手書き日記のきっかけだ。

2月14日から始めたので、間も無く1ヶ月がたとうとしている。日記を書くにあたり、自分が決めたルールはこれ。

  • 日記は事実だけを書く。(何時に起きて、朝食は何を食べたかなど)
  • 日記を書かない日があっても気にしない。
  • 日記は布団で寝転びながら書く。

最後の布団で寝転びながら書くのは、日記を書くという行為のハードルを下げてくれている。これは、セブンルールで新川帆立さんがあげていた「小説はベッドで横になって書く」を丸パクリしたものだ。

www.ktv.jp

この「机に向かう」というハードルを無くすのは本当に効果的だと思う。自分は何か新しいことを始めるとき、様々なことを理由にすぐにやめてしまう。いつも、続かないことが日常なのだ。けど、続けれないことを分析して、障害になっている問題点を取り除こうとする努力を怠っていたことが、何事も長続きしない最大の原因だったのだ。

 これを機に、自分の様々な問題点に向き合って考えるようになってきた。「作ったゲームのダウンロード数が伸びない」→「ダウンロード数が伸びない原因は、そもそもゲームの存在を知られていないから」→「まず認知されないとダメなので、次のゲームリリース時には、メディアにプレリリースを配信してみよう」など。

やっぱり、何事も考えないとダメっすね。と、言葉が出てこないことを発端に、自分の中で新たな指針ができたので、記憶力の低下も悪いもんじゃないね。

【Unity】ゲームを作ってリリースしました。

Unityでゲームを作って、Androidアプリとしてリリースしました!
超絶シンプルですが、今の自分ができることを詰め込みました。無料で広告なしなので、ぜひぜひ遊んでみてください。

play.google.com

f:id:uuc1h:20210204231232p:plain

 

【技術書メモ】配列とList<T>の操作まとめ

普段めちゃめちゃよく使う、配列とList。これは自分だけかも知れないが、普段の仕事で書くコードにあまり配列を使わない印象がある。Listの使用率が圧倒的に多い。
けど、配列が使えないと困る部分はあるので、一緒にまとめていく。

配列あるいはListに同じ値を設定する

あまり使用頻度が少なそうだが、同じ値の要素をもったリスト、配列の作り方。

// -1が20個あるリスト
var numbers = Enumerable.Repeat(-1, 20).ToList();

// -1が20個ある配列
var numbers = Enumerable.Repeat(-1, 20).ToArray();

ちなみに、-1を20個要素にもったリストを作ろうとすると、以下のように書く。
うん、これはだるい。

var numbers = new List<int> {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };

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

ここからのやつは、かなり出番がありそう。

// 1から20まで連続した値をもったリスト
var list = Enumerable.Range(1, 20).ToList();

// 1から20まで連続した値をもった配列
var array = Enumerable.Range(1, 20).ToArray();

平均値を求める

こっから、よく使うやつたちです。

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

合計を求める

var sum = numbers.Sum();

最小値、最大値を得る

var min = numbers.Min();
var max = numbers.Max();

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

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

条件に一致する要素があるか調べる

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

すべての要素が条件を満たしているか調べる

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

2つのコレクション(リストや配列など)の要素が等しいか調べる

bool equal = numbers1.SequenceEqual(numbers2);

条件に一致する最初 / 最後の要素を取得する

var text = "The quick brown fox jumps over the lazy dog";
var words = text.Split(' ');

// 文字列overが取り出される
var word = words.FirstOrDefault(x => x.Length == 4);

// 文字列lazyが取り出される
var word = words.LastOrDefault(x => x.Length == 4);

条件に一致する最初 / 最後のインデックスを求める

var numbers = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
// 戻り値は2
var firstIndex = numbers.FindIndex(n => n < 0);
// 戻り値は8
var lastIndex = numbers.FindLastIndex(n => n < 0);

条件を満たしている間だけ要素を取り出す

これはちょっとつまづいたので、説明を入れる。TakeWhileメソッドを使えば、引数に与えた条件を満たしている間の要素を取り出せる。しかし、先頭から順番に条件に当てはまるか調べるが、先頭がすでに条件から外れていたら、その時点で処理をストップする。だから、以下コードのようになる。

var numbers = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
// 9, 7を取り出す
var selected = numbers.TakeWhile(x => x > 0);

// 何も取り出さない
var selected = numbers.TakeWhile(x => x < 0);

条件を満たしている間は要素を読み飛ばす

今度は、条件を満たしている間は要素を読み飛ばす。ただ、先頭が条件に合わないと処理がストップする動きは同じ。

var numbers = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
// -5, -4, 2, 5, 4, 0, -4を取り出す
var selected = numbers.SkipWhile(x => x > 0);

// 9, 7, -5, -4, 2, 5, 4, 0, -4を取り出す
var selected = numbers.SkipWhile(x => x < 0);

リストの重複を排除する

var numbers = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
var result = numbers.Distinct();

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

この並び替えは、めちゃめちゃ使うと思う。かなり重要。

// 昇順にソート
var numbers = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
var selected = numbers.OrderBy(x => x).ToList();
selected.ForEach(Console.WriteLine);

// 降順にソート
var selected = numbers.OrderByDescending(x => x);

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

var numbers1 = new List<int> { 9, 7, -5, -4, 2, 5, 4, 0, -4, };
var numbers2 = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, };

var all = numbers1.Concat(numbers2).ToList();
all.ForEach(Console.WriteLine);

ここに書いたものが、すっと出てくるようになれば競プロもだいぶ解けるようになるんじゃないかと思う。反復あるのみですね。
配列とList、完璧に理解した。

【技術書メモ】文字列の操作まとめ

Atcoderなんかのような競技プログラミングをやっていると、必ず出てくるのが文字列の操作。文字列の中からある文字列を削除したり、くっつけたりと、そういった類の問題が出てくる印象がある。
で、ここらへんはすでにメソッドが用意されているので、知っていると知っていないでは、問題の解くスピードが変わってくる。けどね、全部を覚えるのは不可能です。じゃあ、どうしたらいいか考えた結果、メソッド自体を覚えるのではなく、「文字列の比較で、大文字と小文字の区別なく比較できるメソッドあったな」みたいに、こんなことができるメソッドがあったなということを覚えておけばいい感じだと思う。
で、これらを覚えておくには、ソースを書いて、そのメソッドを使ってみないとダメだ。ということで、以下つらつらと書いていきます。

文字列どうしの比較

var str1 = "ABC";
var str2 = "ABC";

if(str1 == str2) 
    Console.WriteLine("OK");

一番シンプルなやつ。演算子が==なので、直感的でわかりやすい。

大文字 / 小文字の区別なく比較する

var str1 = "windows";
var str2 = "WINDOWS";

if(String.Compare(str1, str2, ignoreCase:true) == 0) {

    Console.WriteLine("等しい");

} else {

    Console.WriteLine("等しくない");

}

String.Compareを使えば、文字列比較の幅が一気に広がる。
これより以下、String.Compareを使った文字列比較の例。

ひらがな / カタカナの区別なく比較する

var str1 = "カステラ";
var str2 = "かすてら";

// CultureInfoクラスは、言語、国、地域、暦などを表すクラス
var cultureInfo = new CultureInfo("ja-JP");
if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreKanaType) == 0) {

    Console.WriteLine("等しい");

} else {

    Console.WriteLine("等しくない");

}

全角 / 半角の区別なく比較する

var str1 = "HTML5";
var str2 = "HTML5;

// CultureInfoクラスは、言語、国、地域、暦などを表すクラス
var cultureInfo = new CultureInfo("ja-JP");
if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreWidth) == 0) {

    Console.WriteLine("等しい");

} else {

    Console.WriteLine("等しくない");

}

ここまでString.Compareメソッドを使った、文字列比較をまとめてきた。次は、文字列の判定についてまとめてみる。ここで出てくる、「指定した部分文字列で始まっているか」などは、競プロでほんとよく出てくる。

nullあるいは空文字列かを調べる

var str = "";

if (String.IsNullOrEmpty(str))
    Console.WriteLine("NG");

文字列のNULLと空文字チェックだが、自分が何も考えずに書くと以下のようになってしまう。

var str = "";

if (str == null || str == "")
    Console.WriteLine("NG");

こっちでも動くけど、IsNullOrEmptyメソッド使った方が分かりやすいし、確実だな。if文の条件は、バグポイントなので。
ちなみに、空白文字列まで調べられるメソッドもある。

if (String.IsNullOrWhiteSpace(str))

指定した部分文字列で始まっているか調べる

var str = "Visual Studio";

if (str.StartsWith("Visual"))
    Console.WriteLine("OK");

指定した部分文字列で終わっているか調べる

始まりがあれば終わりもあるということで、終わりを調べるメソッドもある。

if (str.EndsWith("Visual"))

指定した部分文字列が含まれているか調べる

始まりと終わりときて次は、そもそも場所関係なく部分文字列が含まれているかどうかを調べるときには、Containsメソッドを使う。

if (str.Contains("Program"))

条件を満たしている文字が含まれているか調べる

Anyメソッドの引数の条件に合う文字があれば、trueを返す。

var target = "C# Programming";
var isExists = target.Any(c => Char.IsLower(c));

すべての文字がある条件を満たしているか調べる

さきほどは、一つでも条件を満たした文字があるか調べるものだったが、今度はすべての文字が条件を満たしているか調べる。以下のコードだと、target変数の文字が、すべて数字だったら、trueを返す。

var target = "141421356";
var isAllDigits = target.All(c => Char.IsDigit(c));

部分文字列を検索し、その位置を求める

これも、競プロでよく使うイメージがある。先頭を0から数えた、インデックスを返す。

var target = "C# Programming";
var index = target.IndexOf("Programming");

文字列の一部を取り出す

SubStringメソッドを使えば、開始位置と長さを指定することで、任意の文字列を取り出せる。

var target = "C# Programming";
// 文字列"Pr"を取り出す
var value = target.Substring(3, 2);

ちなみに、Substringの第二引数に何も指定しなければ、文字列の最後まで取り出す。

var target = "C# Programming";
// 文字列"Programming"を取り出す
var value = target.Substring(3);

残り、ちょっと一気に書く。

文字列の前後の空白を取り除く

var target = " C# Programming ";
var replaced = target.Trim();

指定した位置から任意の数の文字を削除

var target = "01234ABC567";
// 開始位置と長さを指定
var result = target.Remove(5, 3);

文字列に別の文字列を挿入する

var target = "01234";
// 01abc234を返す
var result = target.Insert(2, "abc");

文字列の一部を別の文字列で置き換える

var target = "I hope you";
var replaced = target.Replace("hope", "wish");

小文字⇆大文字の変換

var replaced = target.ToUpper();
var replaced = target.ToLower();

指定した区切り文字で文字列配列を連結

var languages = new [] {"C#", "Java", "VB", "Ruby", };
var separator = ",";
// 文字列"C", Java, VB, Ruby"を返す
var result = String.Join(separator, languages);

文字列から文字を1つずつ取り出す

var str = "C"プログラミング";
foreach (var c in str)
    Console.Write("{0}", c);

文字配列から文字列を生成

var chars = new char[] {'P', 'r', 'o', 'g', 'r', 'a', 'm' };
var str = new string(chars);