ゲームが面白い理由

https://www.youtube.com/watch?v=7PbpvkV_huM
自分の考えとしては、習熟(おおまかに言うと上手くなること)が面白い理由だと思う。
現代のゲームは総合芸術なのでいろんな楽しい要素があるが、選択と評価があることがゲームの要件で、「楽しい」ゲームの要件にはさらに習熟という要素があると思う。
具体例をあげていく。

くじ引き

これは「楽しく」ない。
これには選択と評価がある。カイジが会長とやったくじ引き勝負(イカサマは無しとする)はゲームである。

「正解の候補が1か2しかないハイ&ローゲーム」

次に出す例との比較としてこれを上げるが、これには運以外に結果をコントロールする手段が無い。
そういう意味でくじ引きと変わらない。
これは「楽しく」ない。

「正解の候補が1~100ならハイ&ローゲーム」

正しい手法と正しくない手法があり習熟の要素がある。
これは「楽しい」。

keep-alive

https://e-words.jp/w/HTTP%E3%82%AD%E3%83%BC%E3%83%97%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96.html
初期のHTTPは一回の送受信のために接続を確立し、転送が終わると切断するという仕様だった。
現在はWebサーバとWebブラウザ間の通信では、TCPコネクションが維持され続けるようになって、リクエストやレスポンスの送受信に繰り返し使われる。
HTTP 1.1からは特に指定がなければコネクションが継続され、ヘッダ中で「Connection: Close」を宣言すると切断される。
(明示的に接続維持する場合は「Connection: Keep-Alive」と宣言する)

simスワップ

https://nordvpn.com/ja/blog/sim-swap-fraud/
ソーシャルハック(つまりは普通の詐欺)で他人の携帯電話のsimカードを入手することでアカウントを奪う攻撃。

仮に銀行やSNSのアカウントのIDやパスワードがわからない場合でも、再設定をリクエストすると、
2段階認証としてアカウントにアクセスするためのリンクまたはワンタイムパスコードが
電話番号のSMS宛にテキストで送信され、アクセスできるようになります。

これはシステム設計もダメなのでは……。
セキュリティは一番弱いところが破られるので、普段は2要素認証(パスワード知識+スマホ所持)でログインできるようにしてて、特定操作をすれば1要素認証(今回の場合スマホ所持)のみでログインできちゃうなら、それは意味をなしていない。

手続き型と関数型のコード比較が卑怯

https://kentutorialbook.github.io/functionalprogramming2022/
手続き型であれば以下のコードが……

let sum = 0;
let x = 0;

for (let i = 0; i < 10; i++) {
  x = x + 1;
  sum = sum + x;
}

console.log(sum);

関数型だと、こうなります。

const add = (a, b) => a + b;
const sum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(add);

console.log(sum);

関数型は素晴らしい。
……という主張は卑怯である。
まず関数型サンプルで「1, 2, 3, 4, 5, 6, 7, 8, 9, 10」をベタに書いてあるのは手続き型と等価なコードとは言えない。
そして関数型サンプルは「reduce」というシステム側で用意されたロジックを使っている点がフェアではない。
この比較をフェアに行うならば、関数型サンプルコードは以下のようなものになるべきだろう。

const add = (a, b) => a + b;
const range = (min, max) => ( min == max ? [min] : [min, ...range(min+1, max)] );
const reduce = (ls, f, acc) => ( ls.length == 0 ? acc : f(reduce(ls.slice(0, -1), f, acc), ls[ls.length-1]) );
const sum = reduce(range(1, 10), add, 0);
console.log(sum);
// ※sliceは配列操作なので「ロジック」ではないという前提で書いている。実際haskellではx:xsのような文法として取り込まれているので。

もちろんこれは揚げ足取りでしかなく関数型の本質的なメリットはいささか減りはしないが、ちょっと不当なコード比較になっているんじゃないか?と思った。



わざわざreduceを定義している上の例は逆に関数型言語に不利な気もする。
フェアなのはこっちか?

const total = (ls) => ( ls.length == 0 ? 0 : ls[0] + total(ls.slice(1)) );
const range = (min, max) => ( min == max ? [min] : [min, ...range(min+1, max)] );
const sum = total(range(1, 10));
console.log(sum);

Your letter has been rejected.

クリア。
30分程度でオンラインで無料プレイできる作品。
手紙の検閲官となり、手紙の内容をチェックして許可か却下かを判別していく、「Papers, Please」ライク作品。
まあそれなりに面白いが、ストーリー的に大きな起伏があるわけではない。
途中、最終的には複数の手紙を組み合わせたら暗号入りになるだと分かる怪しい手紙があるが、それを「却下」判定するとゲームオーバーになる仕様は納得行かない。

1であるビット数を数えるコード

http://www.mwsoft.jp/programming/java/java_lang_integer_bit_count.html

i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;

理由はよくわからないが、2ビットの数から上位ビットが1なら1引くと、なぜか1であるビット数が求まる。具体例は以下。

数えたい数 → 計算 → 1であるビットの数
00 → 00 - 0 → 00
01 → 01 - 0 → 01
10 → 10 - 1 → 01
11 → 11 - 1 → 10

これを2ビットごとにデータを区切って、一気にやっているのが最初の行。
その後、2ビットごとを集計して4ビットにし、4ビットを集計して8ビットにし、8ビットを集計して16ビットにし、16ビットを集計して32bit全体のビット数カウントにする。
ちなみに「>>>」は「符号なし右シフト」の演算子である。