スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書く事で広告が消せます。

オセロ(その12)

さあ、ラストいきましょう。
コメントで人口無能と呼ばれたAIの登場です。

単純に配列を左端から 1列ずつ見ていって
board[x][y] = 0, かつ checkPiece(x, y, true)で置き、
もしも置けたら、turnChange関数に返すという流れのためこう呼ばれます。

たしかに思考しない思考ルーチンですが、
こんなことよくもまあ思いつくものだなあと感心です。


これを、そのまま書けばこんな感じになります。



その12_1メモその12_1ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)


しかしこれを 特殊な流れで行えば
歯ごたえのある対戦相手になるのではないでしょうか?
例えば、4隅(外枠)から探索していくならば結構強くなるのでは?


本当に今、急ごしらえで作ってみるとこんな感じです。



いろんなところがダブってて申し訳ありません。
あと、どうやらバグがありますね。
後日、ちゃんと考えます。


長かったですが、これにて完成です。
動画とは関数の並びが違ったり記述の内容も変えてしまいましたが
if文、for文、while文程度の知識があれば理解できるのではないでしょうか?

関数同士が複雑に絡み合うスパゲッティプログラムと
紀平さんもおっしゃっていますが、それにしても

これを1時間で作ってしまうというのは、ものスゴイ話ですよね。
テトリスに続いてFlashと、新しい動画もできているようです。
ああ、C++を勉強してからテトリスの解説か……。


でも、やっぱりプログラミングって面白いですね。
また、勉強して解説してみますので、どうぞよろしくお願いします。

ここで動画53:26~1:00:00までです。

お疲れ様でした。

テーマ : プログラミング
ジャンル : コンピュータ

オセロ(その11)

GAME OVERになって終了したので
白が何個、黒が何個で、どっちの勝ちかを判断します。

まずは turnChange関数の中で、カウント用の変数 b, w を宣言します。

紀平さんはこの変数を自分でアレンジしておきながら
忘れてバグを頻発させていましたが、
あるあるです。

というか、それらのバグをものすごい勢いで
発見
していく様のほうが圧巻でした。


で、 1回パスが起きた後の for文でカウントさせます。
最後にそのメッセージを表示すれば終了です。

このプログラムなんですが、無駄なカウントが多い気がします。
ソースコードはあっさりしていますが、b, w のカウントに無駄があります




その11_1メモ帳その11_1ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)



3項演算子がわかりにくかったので if文で書いてみました。
では、アラートでなく<div id = "board"></div>に
メッセージを入れて表示してみましょう。

紀平さんはここでいきなりinnerHTMLプロパティを使います。
私は面食らいましたが、JavaScriptでは当たり前の命令のようです。
まあ、オブジェクト指向なのでVBAみたいに知らないと使えない命令があるんですね。



その11_2メモ帳その11_2ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)



アラートがあるほうが便利なので残しました。

これで人対人のオセロが完成になります。
前回と併せてここで動画30:42~53:26までです。
で、続きは次回へ。

テーマ : プログラミング
ジャンル : コンピュータ

オセロ(その10)

もう遊べることは遊べるのですが、
コマを置けない場合の「パス」ができません。

紀平さんはそのことに気づかれていましたが
私ならこの時点で完成にして満足していますね。


では、「パス」して、ターンを交代する turnChange関数を作ります。
これは、onclick関数中で動かしていくことにしましょう。

まず、 turnChange関数中に showBoard関数
turn = 3 - turn の働きを持たせて、
onclick関数に突っ込みます。

ひとまず、これで動かすことができますが、問題(?)があります。

このプログラムは全体の出発点が onload関数です。
しかし、turnChange関数は onclick関数の中だけしか記述されていません。
つまり、ボードが表示され、クリックされないとパスできないのです。

初期状態でいきなりパスすることはゲームの流れ上ありえませんが、
デバッグやらなんやらの都合上、困ることが多い気がします。


そこで、グローバル変数turnを初期値を決めずに宣言しておき、
onload関数の頭ですぐに 変数turn を 2(白)にします。

さらに、turnChange関数の頭に turn = 3 - turn をセット。

初期配置を決めたらいきなりturnChange関数を呼び出して
そこで初めてボードを表示するという手段をとります。

紀平さんはお気に召していませんがまあアリではないかなと思います。
それより私は、この後の turnChange関数の肥大ぶりが気にかかります。



では turnChange関数の中身に話を戻して、
コマを置ける猶予が全ボード中に存在するかを調べます。

つまり、board[x][y] を8×8で調査していって

1. それがboard[][] = 0 (何もおかれていないブロック)であり、かつ
2. checkPiece(x, y, false) (置いたら隣のどれかがひっくり返せる)

という条件のブロックがあれば
showBoard関数に値をリターンして
続行(ふたたびonclick待ち)という流れ。

上記のこれは置けた場合の動きです。

この流れが働かないという場合は、置ける場所がないのです。
よって、パスと表示させて新たに turn = 3 - turn させます。

さらに、置ける猶予があるかどうかをチェックして
(for文で全配列を回して checkPiece() && board[][] == 0)
置ければ問題ないが、猶予がなくパスが 2連続で起きたら終了する。

それが以下のソースになります。



その10_2メモ帳その10_1_2ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)



勝敗判定と新たな<メッセージ>の処理は次にまわすことにして。
アラート表示によるパスの仕組みができあがりました。
今回は私が説明しやすいようにオリジナルです。

で、続きは次回へ。

テーマ : プログラミング
ジャンル : コンピュータ

オセロ(その9)

マスにコマが置けるようになりましたら、
挟んだコマをひっくり返しましょう。

ひとまず、いま置かれたブロックを中心にして
周囲に別の色が置かれたブロックがあるかどうかをチェックします。
これが checkOkeru関数、じゃなかった checkPiece関数なわけですね。

変数名やら関数名が yokujituとか seitoCountとかよくある話です。
後日見て意味や働きががわかるように自作関数には日本語と英語が混ざります。
まあ、そうは言っても、私の場合は間違いなく英語の勉強をしたほうがいいですけどね。


関数中の引数 flip には onclick関数で true を代入。
で、ひっくり返せる枚数 ret に 0以外が返ってくれば動きます。
if (checkPiece(_x, _y, true)) { }; っていうのはそういうことですよね。

わかりにくい部分ですが頑張りましょう。

クリックされると checkPiece関数を呼び出して flip に true が代入されます。
結果、裏返せる枚数(全部の n の数)である ret がリターンされますが
それが 0 じゃなければ(返せるコマがあれば)動きます。


いっぽう、変数に turn(1:黒, 2:白) を用意します。
そして、9個の配列[dx][dy]を使って検索するわけです。

[-1][-1],[-1][ 0],[-1][+1],
[ 0][-1],[ 0][ 0],[ 0][+1],
[+1][-1],[+1][ 0],[+1][+1];


中心(置いたブロック)はスルーさせます。
そして、将来的には x += dx, y += dy と見ていくことで
特定のブロックから放射状にブロックをチェックしていけるようになります。


ようするに、x += dx は x = x + dxで,
y += dy は y = y + dy なので、

《[-1][-1]方向なら》
   [x+(-1)][y+(-1)] --> [(x-1)+(-1)][(y-1)+(-1)] --> ……、
  と左斜め上方向へ。


《[ 0][+1]方向なら》
  [x+( 0)][y+(+1)] --> [(x+0)+( 0)][(y+1)+(+1)] --> ……、
  と垂直に下方向へ。

  1) 方向を決める。
  2) その方向を探索する。
  3) ひっくり返せるならその枚数をretに。
  4) 別の方向に変える。→ 2)へ


[-1-1][-1-1],[-1-1][ 0+0],[-1-1][+1+1],
[-1][-1],[-1][ 0],[-1][+1],
[ 0+0][-1-1],[ 0][-1],[ 0][ 0],[ 0][+1],[ 0+0][+1+1],
[+1][-1],[+1][ 0],[+1][+1],
[+1+1][-1-1],[+1+1][ 0+0],[+1+1][+1+1];


と検索していけるというわけです。
こうして配列の値が 1か 2かを見ていくんですね。
(シューティングゲームの弾の動きを勉強するともっと色々できそうな予感です)

で、置いたブロックに隣接するかたちで違うブロックが置かれていて、
かつ検索の結果、最終的に置いたブロックと同じ色のブロックが出てくれば
最初に置こうと思った場所に Okeruという考え方です。

これを onclick関数に組み込むことでチェックできます
(実際にはひっくり返すまでやります)



その9_1メモ帳その9_1ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)




置いて裏返ってターン交代までいけました。

今回作られたcheckPiece関数の flip が false なら
そこにはコマが置ける猶予があるということを覚えておきましょう。

ここで動画21:08~30:42までです。
で、続きは次回へ。

テーマ : プログラミング
ジャンル : コンピュータ

オセロ(その8)

元となる盤を眺めておりますと、
クリックしたい衝動に駆られるのが人の性です。

では、「何も置かれていない」ブロックをクリックしたら
したところを「黒が置かれた」ブロックに変わるようにします。

で、紀平さんはしばし考えてから
クロージャを使って解決しましょう」とつぶやきます。

ああ、私にはさっぱり理解できないクロージャさんの登場です。
なんか関数を使って書いたら変数に値が保持されるような
そんなもやっと適当な知識しかないクロージャの登場です。

ここまでもそうですが、ここからだいぶ私の妄想で解説します。
あ、今さら言うのも何ですが、ここまでもほとんど私の妄想で解説しています。




その8_1メモ帳その8_1ブラウザ
メモ帳画像
(クリックで拡大)
ブラウザ画像
(クリックで拡大)


まず、紀平さんは当たり前のように showBoard関数の for文の途中に
onclick関数を作りますが、私は「あーそこに作ればいいのか」と
導入部から感心しました。

そして、え~と、_x と _yが値を保持するのはわかりますが、

配列のboard[_x][_y]までもが値を保持しているように見えますよね。
まったくクロージャがわからない私には魔法のようです。

クロージャはshowBoard関数に値を返しているだけで
var board = []が関数の外で宣言されているから
変えた値が残るだけなのでしょうか?

わかる方がいたら教えていただきたいです。

ただ、onclick関数によってクリックされた場所の配列の値が 1(黒)に変更されて、
それがshowBoard関数によって表示されている様はわかりますよね。

ここで動画19:06~21:08までです。
今回はこんな感じで逃げます続きは次回。

テーマ : プログラミング
ジャンル : コンピュータ

訪問者数
累積訪問者数:現在の閲覧者数:
ランキングに参加してみました。
これってなんか、
メリットあるのでしょうか。
free
カテゴリ
最新記事
kuroちゃんclock
プロフィール

Author:伊藤風太郎
職業訓練所でプログラミングを学び、国家資格・基本情報技術者に合格した32歳男。プログラマ・システムエンジニアを目指して有意就職活動中。

最新コメント
最新トラックバック
検索フォーム
リンク
Powered By FC2ブログ

今すぐブログを作ろう!

Powered By FC2ブログ

ブロとも申請フォーム

この人とブロともになる

QRコード
QR