夕暮ログ

C#やJavascript、最近はAndroidなんかも好きなtinqのブログ。「夕暮れログ」

スポンサーサイト

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

C#でアルファベットタイピング、GUI版

前の記事で、タイピングを日本語に対応させるといいましたが、ひとまずのものはできましたが、バグが多くて(というか、不安定で)公開できず。それを元に1から作り直しています。
ですが、時間がとれずになかなかはかどらないです。
ということで、前回のアルファベットタイピングクラスを利用した、GUI版のタイピングゲームです。
といっても、かなり簡易的なものです。
Questionsに入っている文字列を順番にタイピングの問題として出します。KeyPressイベントで入力を行っています。(同じクラス中のため、overrideでイベント設定を省いています。)
かえってきた結果と、タイピングクラスが返す値を描画します。
未入力と入力済みで色を変えるわけですが、横幅の取得が空白が入ったり、何とか省いても1、2pxずれが生じて入力するたびにちかちかするので、1文字ずつ横幅を処理しています。(毎回計算しているので効率はよくないでしょう。問題ロード時にまとめて処理して配列に格納しておいたほうがいいかもしれません。)

間違えると「Miss!」正しい入力だと「Good!」、文字列の入力が完了すると「Clear!」と表示します。
また、すべて入力後にかかった時間と正解数、不正解数を表示します。

▲「Kitty On Your Lap!」WisdomSoftさんでWin32などを勉強している口です^^;
string[] Questions;
Typing t = new Typing();
InputResult status;
int qCount;
bool endFlag = false;

int goodCount = 0;
int badCount = 0;

Stopwatch time = new Stopwatch();
private void Form1_Load(object sender, EventArgs e)
{
    time.Start();
    Questions = new string[] { "void", "int", "hello." , "how are you?" , "Kitty On Your Lap!" };
    qCount = 0;
    SetQuestion();
}

private void SetQuestion()
{
    if (qCount < Questions.Length)
    {
        t.SetQText(Questions[qCount]);
        qCount++;
    }
    else
    {
        endFlag = true;
        time.Stop();
    }
    Refresh();
}

protected override void  OnKeyPress(KeyPressEventArgs e)
{
    char c = e.KeyChar;
    if (endFlag) this.Close();
    if (Regex.IsMatch(c.ToString(), "[a-zA-Z0-9!?,. ]"))
    {
        status = t.InputChar(c);
        Refresh();
        if (status == InputResult.Good || status == InputResult.End) goodCount++;
        else if (status == InputResult.Bad) badCount++;

        if (status == InputResult.End)
        {
            SetQuestion();
        }
    }
    base.OnKeyPress(e);
}

protected override void OnPaint(PaintEventArgs e)
{
    Font font = new Font("MS P ゴシック", 20);
    int count = 0;
    StringFormat sf = new StringFormat( StringFormatFlags.MeasureTrailingSpaces );
    sf.SetMeasurableCharacterRanges( new CharacterRange[] { new CharacterRange(0,1) } );
    
    foreach (var c in t.AlreadyInput)
    {
        e.Graphics.DrawString(c.ToString(), font, Brushes.Red, new PointF(count, 0));
        count += (int)e.Graphics.MeasureCharacterRanges(c.ToString(), font, new RectangleF(0, 0, 100, 100),sf)[0].GetBounds(e.Graphics).Width;
    }
    foreach (var c in t.RemainText)
    {
        e.Graphics.DrawString(c.ToString(), font, Brushes.Blue, new PointF(count, 0));
        count += (int)e.Graphics.MeasureCharacterRanges(c.ToString(), font, new RectangleF(0, 0, 100, 100), sf)[0].GetBounds(e.Graphics).Width;
    }

    switch (status)
    {
        case InputResult.None: break;
        case InputResult.Bad: e.Graphics.DrawString("Miss!", font, Brushes.Black, new PointF(0, 30)); break;
        case InputResult.Good: e.Graphics.DrawString("Good!", font, Brushes.Black, new PointF(0, 30)); break;
        case InputResult.End: e.Graphics.DrawString("OK!", font, Brushes.Black, new PointF(0, 30)); break;
    }
    if (endFlag) e.Graphics.DrawString("正解  : " + goodCount + "\n不正解 : "+ badCount +"\n時間  : "+ time.Elapsed.Seconds +"秒\n何かキーを押すと終了します。",new Font( font.FontFamily ,10 ), Brushes.Black, new PointF(0, 60));
    base.OnPaint(e);
}
enum InputResult
{
    None,   //無効
    Good,   //入力が正しい。   
    Bad,    //ミス   
    End     //入力がすべて完了した   
}
class Typing
{
    string qtext;
    int location;

    public void SetQText(string text)
    {
        qtext = text.Trim();
        location = 0;
    }

    public InputResult InputChar(char c)
    {
        if (Char.ToUpper(qtext[location]) == Char.ToUpper(c))
        {
            location++;
            if (qtext.Length <= (location))
            {
                return InputResult.End;
            }
            if (qtext[location] == ' ') location++;
            return InputResult.Good;
        }
        else
            return InputResult.Bad;
    }

    public string AlreadyInput
    {
        get
        {
            return qtext.Substring(0, location);
        }
    }

    public string RemainText
    {
        get
        {
            return qtext.Substring(location);
        }
    }

    public string QText
    {
        get { return qtext; }
    }
}
関連記事

コメント

ここをクリックしてコメントを投稿

非公開コメント

トラックバック

http://tinqwill.blog59.fc2.com/tb.php/55-8eec5b42

« next  ホーム  prev »

プロフィール

tinq tinq(もしくはTinqWill)

Sky  For   Every 改装予定

プログラミングお勉強中の高校生。月一くらいは更新したい

最新記事

カテゴリ

月別アーカイブ

検索フォーム

最新コメント

リンク

最新トラックバック

FC2Ad

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