2017/06/04

【ハースストーン】チェスの親善試合

ハースストーンの酒場の喧嘩で結構前にあった「チェスの親善試合」が面白かったので、JavaScriptで再現してみました。


下のURLを開いた人同士で対戦できます。
https://arahkesh.kysaeed.com





TODO:
  • 制限時間を作る
  • 切断の扱いを決める
  • もっと軽快にカードを出せるようにしたほうがいいかも
  • 友だちと対戦機能

2017/03/25

SVNManager日本語版

WebブラウザでSubversionサーバのリポジトリを管理するためのツール「SVNManager」の日本語版です。




ダウンロードページ:https://github.com/kysaeed/SVNManagerJP/releases/tag/ver1.10JP
(svnmanager.tar.gzまたはsvnmanager.zipをダウンロードしてください。)



インストール方法、使い方はベースの英語版と同じなので、
英語版の使用方法を解説しているサイト等を参考にしてください。


下記のページが分かりやすかったです。

Subversionサーバをブラウザで管理できるSVNManagerを使おう



2017/03/10

C# : 配列要素のNULLチェック

C#で配列の要素にnullが存在するかをチェックする方法です。



1次元配列にnullが含まれているかチェック

チェック対象が1次元の配列に限定されるなら以下のように、
ArrayのIndexOfメソッドでnullを検索するだけで判定できます。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NullCheck1D
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列
            Object[] testArray1D = { new object(), new object(), null, new object() };

            // nullの存在をチェック
            if (Array.IndexOf(testArray1D, null) > -1)
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }
    }
}



多次元配列に対応

しかし、ArrayのIndexOfメソッドで検索できるのは1次元配列限定なので、
2次元以上の多次元配列(foo[1,2]やbar[1,2,3]のような配列)の配列のnullチェックには使えません。

多次元配列のnullチェックもしたい場合は、多次元配列に対してforeachループを使うと、配列の全要素に対してアクセスできることを利用して、
foreachループ内で配列の要素に対してnullチェックをするようにすれば、配列にnullが含まれているかチェック可能です。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// 多次元配列のnullチェック
/// </summary>
namespace NullCheck2D
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列配列(2次元配列)
            //   ([,]は[2,2]を省略した書き方です)
            Object[,] testArray2D = new Object[,]
            {
                { new Object(), new Object() },
                { null, new Object() }
            };

            // nullの存在をチェック
            if (hasNull(testArray2D))
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }

        /// <summary>
        /// 配列のnullチェック
        /// </summary>
        /// <param name="target">チェック対象の配列</param>
        /// <returns>true=nullあり / false=nullなし</returns>
        static bool hasNull(Array target)
        {
            foreach (Object element in target)
            {
                if (element == null)
                {
                    return true;
                }
            }

            return false;
        }
    }
}



ジャグ配列にも対応

1次元配列、多次元配列には対応できましたが、
配列の要素が配列(ジャグ配列)の場合にも対応したい場合は、配列の要素が配列か(ArrayのArray)をチェックする必要があります。

変数が配列かどうかをチェックするには、Type.IsArrayプロパティを使います。
そして、配列だった場合には、その配列に対して配列のnullチェックをします。
配列要素のnullチェック中に、また配列要素のnullチェックが必要となるとややこしく感じますが、チェック処理を関数化しておいて再帰するだけで、以下のように簡単にできます。

テストコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// 配列のnullチェック(1次元配列、多次元配列、ジャグ配列)
/// </summary>
namespace NullCheck
{
    class Program
    {
        static void Main(string[] args)
        {
            // チェック対象の配列(2次元+ジャグ)
            Object[,] testArray = new Object[,]
            {
                { new Object(), new Object() },
                { new Object[] { new Object(), null }, new Object() }
            };

            // nullの存在をチェック
            if (hasNull(testArray))
            {
                Console.WriteLine("nulあり");
            }
            else
            {
                Console.WriteLine("nulなし");
            }
        }

        /// <summary>
        /// 配列のnullチェック
        /// </summary>
        /// <param name="target">チェック対象の配列</param>
        /// <returns>true=nullあり / false=nullなし</returns>
        static bool hasNull(Array target)
        {
            foreach (Object element in target)
            {
                if (element == null)
                {
                    return true;
                }

                if (element.GetType().IsArray)
                {
                    //要素が配列の場合は、この配列チェック関数に再帰
                    if (hasNull((Array)element))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}





配列をnullチェックしたい場面によって、以上のようなパターンを使分けると便利です。

2010/01/04

PHP : 配列要素のNULLチェック

PHPで配列の要素にNULLが含まれていないかをチェックする方法です。
(C#の場合はこちら

foreachループ内で配列要素を1つ1つチェックすることも可能ですが、
in_array関数を使うと1回の関数呼び出しで配列要素すべてをNULLチェックすることができます。

使い方:
in_array( NULL, 対象の配列, TRUE );
のようにin_array関数でNULLを検索して、戻り値がTRUEの場合はNULLが含まれています。

テストコード:
<?php
//
// 配列の中にNULLが含まれているかのチェック
//

//チェック対象の配列
$params = array(1, 2, NULL, 3);

// 配列の要素をまとめてNULLチェック
$result = in_array(NULL, $params, TRUE); // NULLチェック 戻り値TRUEでNULL有り
if($result){
    print "NULLあり\n";
} else {
    print "NULLなし\n";
}
?>

$_POST/$_GETやデータベースから取得した値等、外部からのデータの配列にNULLが含まれていないかチェックする場合に便利です。

2009/12/15

PHPでEnum (C言語風の連番)

PHPでC言語のEnum型のように、定数値を列挙したくなることがあります。

例えばデータベースに下のようなテーブルを定義したときに、
0が犬、1が猫、2がロバを表していることを(C言語のenumのように)簡潔に表現できる型が欲しくなりますよね。

テーブル:my_friends
id
(数値)
name
(文字列)
type
(数値)
1ポチ0(犬)
2猫太郎1(猫)
3ルシオ2(ロバ)





PHP5.6以降の場合

PHP5.6以降では、arrayにconstを指定できるようになったので、
enumセットをconstなarrayとして定義すると使い勝手が良いです。
(const指定した値は、定数なので$を付けずに使います。)

参考: PHPマニュアル PHP 5.5.xからPHP 5.6.x への移行 http://php.net/manual/ja/migration56.new-features.php

Enum定義サンプル:
<?php
//------------------------------------------------------
// Enum値の定義
//
//   constなarrayを作るだけです
//
const FiendType = array(
    'Dog' => 1,
    'Cat'=> 2,
    'Asinus' => 3,
    'Human' => 10
);


//------------------------------------------------------
// Enum値を使う
//

$type = FriendType['Cat']; // typeに猫を設定します

// switch文でtype別の発言をprintしてみます
switch ($type) {
    case FriendType['Dog']:
        print "ワン\n";
        break;

    case FriendType['Cat']:
        print "ニャー\n";
        break;

    case FriendType['Asinus']:
        print "グーヒー、グーヒー\n";
        break;
}

?>
※ 配列要素の参照方法が間違っていたので修正しました。






PHP5.5以前の場合

5.5より前のバージョンのPHPではconstなarrayは定義できないようなので、
arrayの値を変更できないように保護するクラスを作ってみました。

<?php

//
// PHP(5.5)でEnumを使うためのクラス
//
class Enum
{
    //
    // Enumオブジェクトの生成
    //
    private static $enums = array();
    public static function __callStatic($name, $arguments)
    {
        if (is_array($arguments[0])) {
            // 重複チェック
            if (isset(self::$enums[$name])) {
                trigger_error(print "{$name} is exists..", E_USER_ERROR);
            }
            self::$enums[$name] = new Enum($arguments[0]);
        } else {
            if (!isset(self::$enums[$name])) {
                trigger_error("Enum {$name} not found...", E_USER_ERROR);
            }
            return self::$enums[$name];
        }
    }

    //
    // Enumオブジェクトのメソッド
    //
    protected $values = array(); // Enum要素

    // arrayからEnumオブジェクトを生成
    protected function __construct(array $params)
    {
        // Enum値をプロパティへ
        foreach ($params as $key => $p) {
            if (!is_int($key)) {
                trigger_error('Key must be an int.', E_USER_ERROR);
            }
            $this->values[$p] = $key;
        }
    }

    // Enum要素の取得
    public function __get($name)
    {
        if (!isset($this->values[$name])) {
            // 存在しない要素
            trigger_error("[{$name}] isn't enum element", E_USER_ERROR);
        }
        return $this->values[$name];
    }

    // 代入
    public function __set($name, $value)
    {
        trigger_error("Enum can't set.", E_USER_ERROR);
    }
}
?>


実際に連番を定義する時には、下のように使います。
<?php
//
// 連番の定義
//
//   Enum::'連番の名前'()に対して、arrayを渡すだけです。
//
Enum::FriendType(
    array(
        'Dog',  // 犬
        'Cat',  // 猫
        'Asinus', // ロバ
        10 => 'Human' , //いつか人間のFriendができた時のために10番をHumanにしておく、なんてこともできます
    )
);

?>

Enum::のあとにEnumセットの名前を書いて()の中にEnum要素の名前を配列として渡すだけです。
配列のキーがそのまま各要素の値になっているので、上のHUMANのようにキーを指定すれば、
値を指定した要素を作ることもできます。



上で定義した連番を使う場合は、下のようになります。
<?php

$type = Enum::FriendType()->Cat; // typeに猫を設定します

// switch文でtype別の発言をprintしてみます
switch ($type) {
    case Enum::FriendType()->Dog:
        print "ワン\n";
        break;

    case Enum::FriendType()->Cat:
        print "ニャー\n";
        break;

    case Enum::FriendType()->Asinus:
        print "グーヒー、グーヒー\n";
        break;
}

?>
ここでも、Enum::のあとにEnumセットの名前と()を書き、->で各要素にアクセスします。




もっとオブジェクト指向なJava風Enum(Enamlatableなオブジェクト)を定義したいって時は、PHPでJava風のEnum(なごりんぐ)へ。

2009/12/09

データベースを使うPHPプログラム (2)PDOを使ったPHPプログラムを書く


データベースを使うPHPプログラム (1)からの続き



前回の手順で下のようなテーブルがデータベース内に作成できました。

messagesテーブルに登録したデータ
id
項目番号
message
メッセージ
1やあ。
2DBのメッセージ
3へい!へい!


今回はこのテーブルからデータを取得して表示するPHPプログラムを作成します。


1.PHPプログラムの作成

下のようなPHPのコードを入力します。

<?php

$dbName = 'php_db'; // データベース名
$dbUser = 'php_db'; // ユーザ名
$dbPass = 'php_db'; // パスワード

// データベースへ接続する
try{
 // MySQLへ接続
 $pdo = new PDO(
  'mysql:host=localhost; dbname='.$dbName,
  $dbUser,
  $dbPass,
  array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET CHARACTER SET utf8;')
 );
}
catch(PDOException $e){
 // エラー
 print 'error!<BR />';
 die;
}

// データベースからデータを取得
$query = $pdo->prepare('select * from messages'); // データ取得のSQL文
if( !$query->execute() ){ // SQL文を実行
 // エラー
 print 'execute error!<BR />';
 die;
}

// データベースから取得したデータを表示
while( $row = $query->fetch(PDO::FETCH_OBJ) ){ //データベースから
 print $row->id . ':'; // idフィールドの内容を表示
 print $row->message . '<BR />'; // messageフィールドの内容を表示
}

?>



2009/12/03

データベースを使うPHPプログラム (1)データベース(MySQL)の準備

XAMPPで作ったPHPの開発環境で、データベースを使うプログラムを作ります。



データベースについて


XMAPPにはMySQLというデータベースが含まれています。
まずは、MySQLのデータベースがどのようにデータを格納しているかを説明します。


データベースは複数の要素をテーブルと言う単位でひとまとめにして管理しています。
フィールドというのが実際にデータ1つ1つが登録されている場所です。




データベースの構造

MySQLデータベースサーバ
    |
     +-データベース
            |
            +テーブル
            |     |
            |     +-フィールド
            |     +-フィールド
            |
            +テーブル
                  |
                  +-フィールド
                  +-フィールド



抽象的すぎて分かりづらいので、ブログのデータを保存しているデータベースを例に同じような図にすると下のような感じです。
データの種類ごとにテーブルがあり、テーブル内のフィールドにデータが保存されているのがわかると思います。

ブログデータベース


データベースサーバ
    |
     +-ブログデータベース
            |
            +ブログ記事テーブル
            |     |
            |     +-記事タイトルフィールド
            |     +-記事内容フィールド
            |
            +ブログコメントテーブル
                  |
                  +-コメント投稿者名フィールド
                  +-コメント内容フィールド





今回は、下のようなデータベースからメッセージを取り出して表示するだけの単純なプログラムを作ってみます。


今回作るプログラム用のデータベース

MySQLサーバ
    |
     +-データベース
            |
            +メッセージテーブル
                  |
                  +-項目番号フィールド
                  +-表示メッセージフィールド