Yuki Nakata's Blog

One color just reflects another

vps2


レンタルサーバー VPSはServersManだ!

ServersManのVPSレンタルサーバーを借りています。

もう3台目。格安のEntryを3台。3台借りても1カ月2000円以内に収まります。

気に入りすぎています。

お試しでさくらVPS借りましたが、ダメでした。私には難しすぎます。

私がやりたいことはphpをcronで常時動かしたい!!!

はっきり言ってこれだけなのです。面倒くさいサーバー設定は極力勘弁。

というような人にはServersManがうってつけだと思います。

本当に1時間で本格サーバーを立ち上げることができます。

レンタルサーバー比較ではServersManよりさくらVPSの方がパフォーマンスが上という記事が引っ掛かります。

そうなのでしょうが単純にそうとも言えません。

httpサーバーはデフォルトのApachではなく軽量サーバーのnginxを使います。

またphpはphp5ではなく、php7にするとパフォーマンスが3倍良くなります。

nginxとphp7を組み合わせるとServersmanで十分戦えるのです。

しかも見逃せないのはハードウェアも良くなっている点です。

CPUも以前と比較すると性能が良くなっています。

現在はコレ。Intel(R) Xeon(R) CPU E5-2430L 0 @ 2.00GHz

PHPもサクサクに動きます。

試してみる価値があると思いますよ。

Serversmanの環境
OS ubuntu14.04
httpサーバー nginx
php php7.0
ftpサーバー vsftp
sqlデータベース いらない

参考にしたサイト
以下のサイトをマネすると初心者でも設定できます。

ubuntu ユーザを追加して sudo 権限をつける ユーザーを追加してsudo権限をつける

Ubuntu 14.04 で add-apt-repository が無いと言われた add-apt-repositoryコマンドを追加

Ubuntu14.04にnginxとPHP7.0とMySQL5.7をインストールする nginxとphp7をインストール

Ubuntu 14.04 LTS : FTPサーバー : Vsftpd インストール : Server World vsftpdインストール

/etc/nginx/conf.d/default.conf
rootディレクトリだけ変更した
 
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    
    location / {
        root   /usr/share/nginx/html;
        index  index.php;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}


    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
   

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}


/etc/vsftpd.conf

変更箇所
write_enable=YES
ascii_upload_enable=YES
ascii_download_enable=YES
ls_recurse_enable=YES


img_90ea5e7e5765f1b67af836fe96f123d5186938
アメリカの大統領選挙に注目していました。

2062年の未来人がトランプは大統領にならないと予言していたからです。

結果は大外れ。2分の1も当てられません。これで未来人とは。。

Q「トランプは大統領になるか」

2062年氏「ならない」


少しがっかりしましたよね。

2062年の未来人はそもそも地震を予知できたのでしょうか?

時系列で整理しました。

2010年11月14日 未来人登場 
自然災害に関しては、言う事が許されない。人口動態変化に繋がる事は言えないのだ。 
ただし、忠告しておく。yあ 間 N意 埜 b於 レ いわゆる山に登れ

2010年11月16日 未来人再登場
今回の任務が完了したら2016年4月15日へ行く。また会えたらいいな。

2011年3月11日 東日本大震災 

2016年4月14日~16日 熊本地震

まず2062年の未来人は地震予知をしていません。

山に登れと忠告したのと、2016年4月15日へ行くと言っただけです。

地震とも熊本とも書いていません。

それなのに2チャンネルでは地震予知が当たったと大騒ぎしました。

未来人は地震予知をしていません。アメリカ大統領選挙は予言しました。

大統領選挙ではトランプが勝利し、大外れです。 

残念ですが、やはりインチキでした。

ジョンタイターの予言が酷すぎる 

お前らのアフィリエイトリンク踏んでやるよ!

タイトル通りリンク喜んで踏んであげます。

アフィリエイトクリック派です。

私はアフィリエイトリンクを迷わず勇敢にクリックしますよ。

使っているネットショップは大抵アマゾンです。

アマゾンで1か月10マソぐらいは使っているかなー。

太っ腹だからねー。

踏んであげますよ。

良かったらコメントにでもアドレスを書いておいてくださいませ。

gallery06_daiv_dgz_dqz_l


今狙っているのがマウスコンピューターのDAIVです。

DAIV-DQX700U3-SP2 60万円位。

来年の1月ぐらいを予定しています。

アフィリエイトリンクを張っていたらクリックしますよ。

 

スーパーマリオブラザーズ 人工知能で世界最速を目指そう!

 

これをマネしてやってみたいと思います。

ステージ1-1をクリアできることは確認しています。

スーパーマリオブラザーズ ステージ1-1世界最速を目指して見ましょう。

必要なものはFCEUXというエミュレーターとスーパーマリオブラザーズのロムです。 あとはメモ帳のようなテキストエディタです。

Win、Linux, Macでもできるでしょう。

FCEUXにはコミュニケーション機能が付いており、LuaScriptを使うことでゲームをコントロールすることができます。

私もLuaScriptは初めてでしたが、Pythonみたいなものと思って構いません。ほぼPythonです。

やってみて思ったのが非常に面白い。だってマリオが動くんですから。 300px-スクラッチキャット
スクラッチの猫を動かすようなものです。マリオを動かしてみましょう。

辛気臭いC言語やるよりよっぽど良いでしょう。 

まず初めはhelloworldを表示させます。

ファイル名は何でもいいのですが、SMB-GA.luaにしました。

print ("Hello World!")
スーパーマリオブラザーズを読み込んでSMB-GA.luaを実行するとHello Worldが表示されます。

 fceux1
マリオを右に動かしてみましょう。
print ("Hello World!")

--無限ループ
while true do
  joypad.set(1, {right=true})
  emu.frameadvance()
end 

スタートを押してゲームを開始、スクリプトを実行するとマリオが右へ進みます。
もちろん最初のクリボーにぶつかり、死にます。

ゲームを改造します。
マリオの残機を99にしてみましょう。

ToolからMemory Searchを起動します。
fceux2
アドレス075AのValueというところを見てください。2になっています。

この2がマリオの残り数を表示しています。ここを99にすると99人になります。
同じように点数を12345670、コインを99に変更します。

ゲームによってメモリーの意味が違ってきます。
Super Mario Bros.:RAM map このサイトを参考にするといいでしょう。

fceux3
print ("Hello World!")

--無限ループ
while true do
  joypad.set(1, {right=true})
  
  --マリオの残機を99に変更する
  memory.writebyte(0x075A, 99)
  
  --得点を12345670に変更する
  memory.writebyte(0x07DD, 1);
  memory.writebyte(0x07DE, 2);
  memory.writebyte(0x07DF, 3);
  memory.writebyte(0x07E0, 4);
  memory.writebyte(0x07E1, 5);
  memory.writebyte(0x07E2, 6);
  memory.writebyte(0x07E2, 7);
  
  --コインを99に変更する
  memory.writebyte(0x07ED, 9);
  memory.writebyte(0x07EE, 9);
  
  emu.frameadvance()
end 

ここまでくればできたようなもので、あとはクリアできるようにキーボード入力を入れたらいいだけです。もちろんそこは機械学習で最適化をさせていきます。

難しいです。ある程度こちらで動きを促してやらないと永久にクリアできません。
右を多く、大ジャンプを多くしてやります。

2016/11/23現在のプログラム
60世代ぐらいで1-1をクリアできるようになります。試してみてください。

require("auxlib");
print ("Hello World!")


key = {}

key["up"] = false;
key["left"] = false;
key["down"] = false;
key["right"] = false;
key["A"] = false;
key["B"] = false;
key["start"] = false;
key["select"] = false;

math.randomseed(os.time())


marioCross = {} --マリオの十字キー
marioA = {} --マリオのAボタン
marioB = {} --マリオのBボタン

marioCross2 = {} --マリオの十字キー コピー用
marioA2 = {} --マリオのAボタン コピー用
marioB2 = {} --マリオのBボタン コピー用

marioGeneration = 1 --世代
marioPlayer = 1
marioMaxPlayer = 20 --マリオ20体用意する
marioHalfPlayer = 20 / 2
marioValue1 = {} --評価値 右へ行くほど高くなる
marioValue2 = {} --評価値 降順ソート用
marioValue3 = {} --評価値 値が小さい程優秀なマリオ
totalValue = 0
averageValue = 0
averageValue2 = 0

marioDistance = 0 --マリオが進んだ距離
marioXPosition = 0 -- 0~最大値255までの値をとる
marioHPosition = 0 -- ステージ1-1は12分割される 0~12までの値をとる
totalInput = 100
frameCount = 1
p = 1
q = true
r = true
x = 1
y = 1
tableLen = 0
select = false


function tableReset(t)
for k in pairs (t) do
t[k] = nil
end
for i = 1, marioMaxPlayer do
t[i]  = {}
end
end

--マリオを20体生成する
function marioGenerator()
for i = 1, marioMaxPlayer do
marioCross[i]  = {} 
marioA[i] = {}
marioB[i] = {}
end
for i = 1, marioMaxPlayer do
for j = 1, totalInput do
 marioCross[i][j] = math.random(13)
 marioA[i][j] = math.random(20)
 marioB[i][j] = math.random(10)
 --print(i, j, marioA[i][j])
end
end
end

--マリオを遺伝的アルゴリズムで再生成する
function marioReGenerator()
--table.sort(marioValue2)
--降順でソートする
table.sort(marioValue2, function (a,b) return a>b end)
--print(marioValue1)
--print(marioValue2)
totalValue = 0
averageValue = 0
for i = 1, marioMaxPlayer do
for j = 1, marioMaxPlayer do
 if(marioValue1[i] == marioValue2[j]) then
  marioValue3[i] = j
 end
end
totalValue = totalValue + marioValue1[i]
end
--print(marioValue3)
averageValue = totalValue / marioMaxPlayer
print(marioGeneration.." Generation  averageValue  "..averageValue)
tableReset(marioCross2)
tableReset(marioA2)
tableReset(marioB2)
--優秀なマリオ 1~8位までをコピーする
p = 1
for i = 1, marioMaxPlayer do
if( marioValue3[i] <= 8) then
marioCross2[p] = marioCross[i]
marioA2[p] = marioA[i]
marioB2[p] = marioB[i]
p = p + 1
end
end
tableReset(marioCross)
tableReset(marioA)
tableReset(marioB)
--いわゆる交叉 xとyが選ばれた親マリオの変数
for i = 1, marioMaxPlayer do
x = math.random(8)
y = math.random(8)
for j = 1, totalInput / 2 do
marioCross[i][j] = marioCross2[x][j]
marioA[i][j] = marioA2[x][j]
marioB[i][j] = marioB2[x][j]
end
for j = totalInput / 2, totalInput do
marioCross[i][j] = marioCross2[y][j]
marioA[i][j] = marioA2[y][j]
marioB[i][j] = marioB2[y][j]
end
end
--突然変異
for i = 1, marioMaxPlayer do
for j = 1, totalInput do
r = math.random(100)
if (r == 3) then
marioCross[i][j] = math.random(13)
 marioA[i][j] = math.random(20)
 marioB[i][j] = math.random(10)
end
end
end
if(averageValue2 < averageValue ) then
totalInput = totalInput + 50
end
averageValue2 = averageValue
--print(totalInput)
tableLen =table.maxn(marioCross[1])
--print(tableLen)
for i = 1, marioMaxPlayer do
for j = tableLen + 1, totalInput do
 marioCross[i][j] = math.random(13)
 marioA[i][j] = math.random(20)
 marioB[i][j] = math.random(10)
 --print(i, j, marioA[i][j])
end
end
end

--評価値を計算する
function calculateValue()
marioXPosition = memory.readbyte(0x0086)
--0x006D mario Position max 12
  marioHPosition = memory.readbyte(0x006D)
  marioDistance = marioHPosition * 256 + marioXPosition
  marioValue1[marioPlayer] = marioDistance
  marioValue2[marioPlayer] = marioDistance
  --print(marioPlayer, marioValue1[marioPlayer])
end

--変数初期化 ソフトリセット
function resetFunction()
  marioHPosition = 0
  marioXPosition = 0
  marioDistance = 0
  --totalInput = totalInput + 10
  --marioGenerator()
  
  if(marioPlayer < marioMaxPlayer) then
  --print(marioPlayer)
  marioPlayer = marioPlayer + 1
  else
  --世代交代
 
  marioReGenerator()
  marioPlayer = 1
  marioGeneration = marioGeneration + 1
  end
  emu.softreset()
  frameCount = 1
end


function testiup()
function turboAction(self, a) 
emu.speedmode("maximum")
gui.text(10,10,"pressed me!");
end;
function normalAction(self, a) 
emu.speedmode("normal")
gui.text(10,10,"pressed me!");
end;
-- Create a button
turboButton = iup.button{title="Turbo Speed Button"};
-- Set the callback
turboButton.action = turboAction;
normalButton = iup.button{title="Normal Speed Button"};
normalButton.action = normalAction;
box = iup.vbox {turboButton,normalButton}
-- Create the dialog
dialogs = dialogs + 1;
handles[dialogs] = iup.dialog{ box, title="IupDialog Title"; };
-- Show the dialog (the colon notation is equal 
-- to calling handles[dialogs].show(handles[dialogs]); )
handles[dialogs]:show();

end

testiup();
marioGenerator()

while true do
--if (marioPlayer == 1) then
--print(marioGeneration.."generation")
--end
--print(marioPlayer)
local joy = joypad.read(1)
if (joy["select"]) then
if (select == true) then
emu.speedmode("nothrottle")
gui.text(10,10,"High Speed")
else
emu.speedmode("normal")
gui.text(10,10,"Normal Speed")
end
select = not select
end
--入力が無くなった場合と死亡した場合、評価値を算出しリセット
if(totalInput < frameCount or memory.readbyte(0x075A) == 1) then
memory.writebyte(0x075A, 8)
--print(marioPlayer, totalInput, frameCount, memory.readbyte(0x075A))
    calculateValue()
    resetFunction()
  end

key["up"] = false;
key["down"] = false;
if( marioCross[marioPlayer][frameCount] == 1) then
key["left"] = true;
key["right"] = false;
else
key["right"] = true;
key["left"] = false;
  end

  if(marioA[marioPlayer][frameCount] == 1) then
key["A"] = false;
else
key["A"] = true;
end

  if(marioB[marioPlayer][frameCount] == 1 ) then
key["B"] = false;
else 
key["B"] = true;
end

  -- Execute instructions for FCEUX
  joypad.set(1, key)

  
  

  --スタート画面に戻ったらスタートボタンを押す
  if(memory.readbyte(0x07F8) == 4 and memory.readbyte(0x07F9) == 0  and memory.readbyte(0x07FA) == 1) then
    joypad.set(1, {start = true})
    --print("reset")
    frameCount = 1
  end

  emu.frameadvance() -- This essentially tells FCEUX to keep running

  --print (memory.readbyte(0x0086));

  frameCount = frameCount + 1

やっぱ三国志13は最高傑作だわ

皆さん、三国志13やってますか?

PKが冬に発売されるということで再開しています。

やはり三国志13は誰が何と言おうと歴代最高傑作です。

難易度上級で大国曹操を叩きのめすのが面白い。

難しいけれどコツがわかってきました。

攻略方法を書いていきます。


その1 とにかく速攻
このゲーム時間が経つほど敵が強くなっていきます。

のんびり内政なんかやっていると手の付けようがなくなってしまいます。

できるだけ兵士を出して敵を常時撹乱させていきましょう。


その2 空白都市を占領しない
空白都市があると占領したくなりますが、あえて占領しません。

占領して隣国と接すると敵が攻めてきます。

空白都市を占領しても敵を増やすだけです。

攻められても対処できるとき、余裕がある場合のみ占領します。

その3 戦争する武将を固定する
毎回同じメンバーで戦争しましょう。

戦争するメンバーを最初に決めてしまいましょう。そうすると絆レベルも上がっていきます。

勝利の方程式を作ったら、あとは運用するだけです。

その4 大群で攻めてきたときは、速攻放棄する
曹操軍が大量に攻めてくることがあります。

そういうときは、歯向かっても無駄です。全武将を移動させ、金兵糧もゼロにして明け渡しましょう。

逆にがら空きの城を攻撃します。

その5 おススメの戦法は逆転采配
逆転采配ばかり使っています。

敵を囲んでタコ殴りにするときは逆転采配。ゲージ4なので切れたら速攻逆転采配できます。

陳登が持っています。

使わないのが呂布、張飛、関羽のような戦法。これらはピンチのとき、逆に敵に囲まれたときに威力を発揮します。囲まれることがなければ使いようがありません。

攻略動画を張り付けておきます。

三国志13の攻略動画をうぷしていくよ。

 

今更ですが、IPアドレスのはなしです。

IPアドレスには2種類あります。グローバルとローカル(プライベート)です。

インターネットに接続するにはIPアドレスを取得しなければいけまん。

まずグローバルIPアドレスを確認してみましょう。

CMAN グローバルIPアドレス  ここをクリックするとグローバルIPアドレスが分かります。

パソコンやスマホ、ネットに接続するデバイスにはそれぞれローカルIPアドレスが割り当てられます。 

確認方法はコマンドプロンプトからipconfigを実行します。
ipc4
この画像では192.168.0.3がローカルIPアドレスです。

なぜグローバルとローカルの2つあるのか?

その理由を説明します。

先ほども書いたようにネットに接続するためにはIPアドレスを取得しなければなりません。

もし仮にすべてのPCやスマホ、タブレットがグローバルのIPアドレスを持つとすると、グローバルIPアドレスが一気に枯渇してしまいます。

そのためPCやスマホにはローカルのIPアドレスを割り当てて、一つのグローバルIPアドレスを使い回す、ということをしています。

郵便を例に説明してみます。というのはネットの仕組みは郵便を真似して作られているからです。

東京都新宿区1町目1-1に磯野家が住んでいたとします。
住民は磯野マスオ、サザエ、カツオ、ワカメ、タラです。

この磯野カツオにハガキを送りたいとします。もちろんこのハガキがhtmlやjpgなどのデータに相当します。

どうすれば磯野カツオにハガキを届けることができるでしょうか。

ハガキの宛先に東京都新宿区1丁目1-1と住所をまず書きます。

これだけで家のポストに届きます。この東京都新宿区1丁目1-1がグローバルIPアドレスです。

グローバルIPアドレスがあればとりあえずポストにまで届きます。

そこから先、磯野カツオと宛名を書けば磯野カツオだなと分かり、ちゃんと届くわけです。

この磯野カツオがローカルIPアドレスです。

そしてポストの役割がルーターと呼ばれるものです。ルーターはローカルIPアドレスを見て振り分けてくれているのです。

確認しておきたいことは、磯野家の住民が100人いようが、グローバルIPアドレス(東京都新宿区1丁目1-1の住所)を使い回しているのでたった一つで済んでいることです。

これで仕組みがわかりましたでしょうか。
ip-image
コニファさんの画像。見たらなんとなく分かると思います。

最後にグローバルIPアドレスはネットに晒しません。住所を公開するようなものです。世界で一つであり、原理的に追跡が可能です。

ローカルIPアドレスは晒しても問題ありません。追跡のしようがありません。
 

Raspberry pi3にretropiをインストールしてみました。

プレイステーションもN64も全く遅延がありません。快適に遊べます。

新たにmicroSDカードを購入。一枚のmicroSDカードを使い回すのではなくOS毎にSDカードを持っておくと便利です。ラズベリーパイに入れ替えるだけですからね。

retropiを使うとラズベリーパイをゲーム用マシンにすることができます。 ファミコン、スーパーファミコン、アーケード、64などの主要なエミュレーターが含まれています。

RetroPie から RetroPi 4.0.2をダウンロードします。現在最新は4.0.2です。
解凍してimgファイルを取り出します。

microSDをSDFormatter を使ってフォーマットします。
sdformatter
オプション設定から上書きフォーマット 論理調整 ONでフォーマットします。

取り出したimgをWin32DiskImagerを使って書き込みます。
win32diskimager
出来たらmicroSDカードを取り出しラズベリーパイに装着します。

ゲームコントローラーを付けてラズパイの電源を入れます。
cf42f25c-3cee-11e5-8f91-c1fc1c57175c
ゲームコントローラーのボタンを割り当てていきます。

Logicool F310を使っています。下の画像と同じように設定。
7f353148-42c0-11e6-9023-dbaf074bc933

割り当てるボタンがなかったり、スキップしたい場合にはAボタン長押しです。

c6bbdb3a-3734-11e6-998f-8cc714a320ce
EmulationStationが現れます。retropiのエミュレーターの統括プログラムをEmulationStationといいます。

ここで1時間ハマりました。何をしていいかわからない。ゲームが遊べないので困りました。Romをフォルダに入れるとNESやSNES, MAMEの選択肢が出てきます。

最初にネットワークにつなぎましょう。有線LANでつないでいますが、無線の場合にはメニューからConfigure Wifiで無線設定をします。
7ed23ec0-3cf5-11e5-9944-a8f7870cc6c0
無線の場合
92b08b8c-3735-11e6-8f20-5d1550af0882

ネットに接続されたらIPアドレスを確認します。SHOW IP

この場合は192.168.0.19です。これを覚えておきます。

RETROPIE SETUPからBasic Installをしました。
エミュレーターのインストールが始まります。大分時間がかかります。


RETROPI SETUPからエミュレーター単体で追加インストールすることもできます。

あとはラズパイにロムを転送します。
指定のディレクトリにロムを放り込めばいいのですが、Filezillaを使うのが一番簡単だと思います。
retropiがネット接続できていれば、filezillaからファイル転送することができます。
Filezilla clientをダウンロードして実行します。
filezilla
ホストにIPアドレス 192.168.0.19 
ユーザー名 pi
パスワード raspberry
ポート 22 で接続できます。

ファミコンの場合には/home/pi/RetroPie/roms/nes
スーファミ /home/pi/RetroPie/roms/snes
N64  /home/pi/RetroPie/roms/n64
アーケード /home/pi/RetroPie/roms/mame-mame4all
アーケードゲームの場合注意が必要です。
ロムのバージョンが0.37b5でなければ動作しません。
真っ黒の画面でクラッシュする場合にはロムセットが間違っている可能性があります。
zipでmame-mame4allのディレクトリに入れます。
RetroPie Mame

PS1 /home/pi/RetroPie/roms/psx
cueとbinをpsxディレクトリに入れます。
bios SCPH1001.BIN を/home/pi/RetroPie/BIOS
プレイステーションはcueファイルがないと動作しません。
Playstation Cue FIle cueファイルがここで手に入るようです。
RetroPie PlayStation

このように放り込むロムのディレクトリが指定されています。
日本語のファイル名は文字化けします。

ロムを放り込むと初期の画面が変わります。 

メニューが変わり、ゲームが選べるようになった。 

音はHDMIから出力されるようになっています。
イヤホンに変更する場合にはemulationstationを一旦終了するとコマンドが打てるようになります。
$ amixer cset numid=3 1     イヤホンに音を出力させる

$amixer cset numid=3 2       HDMIに音を出力させる

音量設定 パーセンテージで指定します。 50%~100%で指定します。
$ amixer cset numid=1 70%
70%ぐらいがおすすめです。 50%以下だと何も聞こえなくなります。 

↑このページのトップヘ