今回は TouchShield Slide を使って三目並べを作ってみたので紹介します。

fig4-1.JPG


■三目並べのルール
 三目並べのルールをおさらいしておきます。2人のプレーヤが、3×3のマス目に交互に○と×を描いていき、先に3つ○か×が並んだ方が勝ちです。コンピュータ上では3×3の2次元配列で盤面表現をして、空き、○、×を記憶しておき、勝ち負けの判定をします。

■ゲームの流れ
 プレーヤの数(1: 人 vs コンピュータ、2: 人 vs 人)を入力してから、ゲームを開始することにします。ゲーム前には、乱数を初期化し、盤面の記憶を初期化して、盤を表示します。ゲーム中は、プレーヤが交互に○と×を入れていきます。勝ち負けの判定は、○×を入れるたびに行います。ゲームが終了したら、勝者を表示します。
 TouchSheild Slide だけにスケッチを用意し、Arduino側は使っていません。スケッチの loop() 関数は次のようになりました。

void loop()
{
  // プレーヤの数を入力
  NumPlayers = GetNumPlayers(); // Player の数を確認

  // ゲーム前の初期化
  randomSeed(millis()); // 乱数の初期化
  InitBoard();                  // 盤面を記憶している配列の初期化
  DrawBackGround();             // マス目を表示する

  // 三目並べ
  int winner;
  while(1) {
    CheckTouch(1);              // Player 1 の番
    if (winner = CheckWinner()) // ゲームが終了したか確認
      break;
    if (NumPlayers == 1) // Player 2 の番
      PlayComputer(2);          // Player 2 がコンピュータ
    else
      CheckTouch(2);            // Player 2 も人
    if (winner = CheckWinner()) // ゲームが終了したか確認
      break;
  }

  // ゲーム終了後の勝者の表示
  DrawResult(winner);
}
■プレーヤの数の入力
 TButton を使って入力をします。まず背景を消してから、ボタンを表示し、いずれかのボタンがタッチされるまで待っています。

fig4-2.JPG
int GetNumPlayers()
{
  background(0);  
  OnePlayer.Paint();
  TwoPlayer.Paint();

  while (1) {
    if (OnePlayer.GetTouch()) {
      return 1;
    }
    if (TwoPlayer.GetTouch()) {
      return 2;
    }
  }
}

■マス目の判定
 どのマス目に触ったかを、CheckTouch() 関数で判定しています。タッチされるまで待って、座標からマス目を判定しています。マス目がすでに埋まっている場合は、別の場所をタッチされるまで待ちます。複数回入力を避けるため、タッチパネルが触れられている間は関数から戻りません。
void CheckTouch(int player)
{
  POINT p;
  int x, y;
  while(1) {
    while (touch_getCursor(&p) == 0) // タッチされるまで待つ
      ;

    if (p.x > 40 && p.x < 120)
      x = 0;
    else if (p.x < 200)
      x = 1;
    else if (p.x < 280)
      x = 2;
    else
      x = -1;

    if (p.y < 80)
      y = 0;
    else if (p.y < 160)
      y = 1;
    else
      y = 2;

    // マス目を埋める
    if (x>=0 && board[x][y] == 0) {
      board[x][y] = player;
      // ○か×を表示する
      DrawCheck(player, x, y);
      while (touch_getCursor(&p) == 1) // 離されるまで待つ
        ;
      return; // 呼び出した関数に戻る
    }
    while (touch_getCursor(&p) == 1) // 離されるまで待つ
      ;
  }
}

■コンピュータの手
 コンピュータの手は戦略という物はなく、乱数を発生してマス目を決め、埋まっていないかどうか確認しています。ここを変えると強くなります。
void PlayComputer(int player)
{
  int x, y;

  while (1) {
    x = random(0, 3);
    y = random(0, 3);
    if (board[x][y] == 0)
      break;
  }
  board[x][y] = player;
  DrawCheck(player, x, y);
}

■勝ち負けの判定
 勝ち負けの判定は CheckWinner 関数でしています。盤面の縦・横・斜めが同じプレーヤの印の場合には勝ちと判定します。また盤面が全部埋まっていれば引き分けとします。以下は CheckWinner 関数の縦のチェックの部分です。
  for (int i=0; i<3; i++) // 縦のチェック
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
      if (board[i][0] == 1)
        return 1; // Player 1 wins
      else if (board[i][0] == 2)
        return 2; // Player 2 wins
    }

■ゲーム結果の表示
 ゲーム結果の表示は、HersheyFonts を使ってみました。プレーヤの数と勝敗の結果で表示内容を変え、OK がタップされるまで待っています。
void DrawResult(int winner)
{
  stroke(255, 0, 0);
  if (NumPlayers == 1) {
    if (winner == 1)
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 0, 40, "    You win", 20, 0, 1);
    else if (winner == 2)
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 0, 40,"     I win", 20, 0, 1);
    else
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 40, 40, "    Draw", 20, 0, 1);
  } 
  else {
    if (winner == 1)
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 20, 40, "Player 1 wins", 20, 0, 1);
    else if (winner == 2)
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 20, 40, "Player 2 wins", 20, 0, 1);
    else
      HersheyDrawCString(kHersheyFont_RowmanTriplex, 40, 40, "    Draw", 20, 0, 1);
  }
  // OK がタップされるまで待つ
  OK.Paint();
  while (OK.GetTouch() == 0) // OK ボタンが押されるまで待つ
    ;
}

■ゲームの様子とスケッチのダウンロード
 スケッチはTS_TickTackToe-110104a.zip をダウンロードしてください。スケッチを書き込めばゲーム開始です。実際に遊んでみると、タッチ位置の判定について、平均をとったりするなどの工夫が必要な場合があるかもしれないように感じました。

 ほかにもいろいろ応用できると思います。本記事が楽しいスケッチをつくるお手伝いになれば幸いです。



(光永 法明)



トラックバック(0)

このブログ記事を参照しているブログ一覧: TouchShield Slide でゲームを作ってみる <4>

このブログ記事に対するトラックバックURL: http://www.eleki-jack.com/mt/mt-tb.cgi/5084







newハイパー・マイコンmbedでインターネット電子工作


マイコンと電子工作 No.6


マイコンと電子工作 No.4


マイコンと電子工作No.1
サポート・ページはこちら