2014年09月17日

C#でバイナリークロック

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その42

■問題 (lunlumo さん)
時刻を二進数相当の表現で出力する時計アプリケーションを書いてください。
20:18の場合,例えば以下の様な出力をするイメージです。

出力例:
■□■□□
□■□□■□

参考: Binary Clock Widget http://www.android-app.info/2009/07/01/binary-clock-widget/

コンソールアプリケーションとして作成。
起動すると、1秒おきに表示が切り替わります。

せっかくなので、時分秒を表示するようにしてみました。
BinaryClockクラス自体は、コンソールアプリケーションに依存していないので WindowsFormsアプリでも、WPFアプリでも利用できます。

BinaryClockのコンストラクタで指定する Action デリゲートで 実際の表示を行います。
Action デリゲート(このコードでは、Printメソッド)は、1秒ごとに呼び出されます。

Printメソッド内では、Console.SetCursorPositionで表示位置を固定しているので、 コンソール画面が流れることはありません。

using System;
using System.Linq;

namespace Doukaku.Org {

    class Program {
        static void Main(string[] args) {
            Program app = new Program();
            app.StartBinClock();
            // Enterキーが押されるまで、時刻を更新し続ける。
            Console.ReadLine();
            app.StopBinClock();
            Console.ReadLine();
        }

        private int left;
        private int top;

        BinaryClock binaryClock;

        public Program() {
            left = Console.CursorLeft;
            top = Console.CursorTop;
        }

        private void StartBinClock() {
            binaryClock = new BinaryClock(Print);
            binaryClock.Start();
        }

        private void StopBinClock() {
            binaryClock.Stop();
        }

        private void Print(string[] lines) {
            Console.SetCursorPosition(left, top);
            Console.WriteLine(lines[0]);
            Console.WriteLine(lines[1]);
            Console.WriteLine(lines[2]);
        }
    }

    // コンソールアプリケーションとして作成
    // 秒も表示するようにしてみた。
    public class BinaryClock {
        public BinaryClock(Action<string[]> action) {
            this.action = action;
        }

        private System.Timers.Timer timer = new System.Timers.Timer();
        private Action<string[]> action;

        public void Start() {
            timer.Interval = 1000;
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }

        public void Stop() {
            timer.Stop();
        }

       private  void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
            DateTime now = DateTime.Now;
            var lines = new string[] {
                HorToString(now),
                MinuteToString(now),
                SecondToString(now),
            };
            action(lines);
        }

        private static string ToBinString(int num, int width) {
            string format = string.Format("{{0,{0}}}", width);
            string s = String.Format(format,
                                     System.Convert.ToString(num, 2));
            return s.Replace('1', '■').Replace('0', '□').Replace(' ', ' ');
        }

        private string HorToString(DateTime dateTime) {
            return ToBinString(dateTime.Hour, 6);
        }
        private string MinuteToString(DateTime dateTime) {
            return ToBinString(dateTime.Minute, 6);
        }
        private string SecondToString(DateTime dateTime) {
            return ToBinString(dateTime.Second, 6);
        }
    }
}



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52382366