C#控制台實現倒計時


原文地址:https://www.cnblogs.com/jingjiangtao/p/14766049.html

效果

文章最后有完整代碼,以下是逐步實現。

准備工作

要在控制台上繪制出數字,可以將控制台看作一個網格,在網格中填充顏色就可以顯示不同的數字。首先在excel中做一個網格來確定大小和坐標:

 

 可以看到,畫布大小是 41 x 11,組成每個數字的網格也都標出了坐標,程序中需要繪制數字時只需要參照這個excel網格就行了。

關於如何將excel的表格修改成正方形,可以參考這篇博客:使用Excel在圖片上添加正方形網格線_zy_like_study的博客-CSDN博客_圖片添加網格線

開始編寫代碼

創建網格

 新建一個 .net 5 控制台項目。因為功能簡單,所以就直接在默認的Program類中用靜態函數實現了。

首先要定義一個 41 x 11 的網格用來展示數字。新建一個類 Cell 表示網格中的每一個格子,Value屬性表示這個格子是否激活,true為激活,false為未激活。

public class Cell
{
    public bool Value { get; set; }
}

接下來要定義網格,可以用一個二維數組來表示,數組的類型就是上面定義的Cell。將這個二維數組定義為類的靜態變量,就可以在類的靜態函數中使用。

private static Cell[,] grid = new Cell[11, 41];

定義完成之后需要初始化網格,對二維數組中的類型進行實例化。Init() 函數遍歷網格數組,實例化每個格子,並顯式將Value設為false

private static void Init()
{
    for (int i = 0; i < grid.GetLength(0); i++)
    {
        for (int j = 0; j < grid.GetLength(1); j++)
        {
            grid[i, j] = new Cell();
            grid[i, j].Value = false;
        }
    }
}

在控制台上顯示網格

現在有了數據,接下來就要將數據展示在控制台上。update() 函數遍歷網格數組,判斷每個格子的Value值,如果為true,就將格子設為白色,如果為false,就將格子設為黑色,其中白色表示激活,黑色表示未激活。

private static void Update()
{
    for (int i = 0; i < grid.GetLength(0); i++)
    {
        for (int j = 0; j < grid.GetLength(1); j++)
        {
            if (grid[i, j].Value)
            {
                SetWhite(i, j);
            }
            else
            {
                SetBlack(i, j);
            }
        }
    }
}

SetWhite()函數和SetBlack()函數調用了C#控制台的接口,將指定位置的背景設為指定顏色。

private static void SetWhite(int i, int j)
{
    string fill = "  "; // 兩個空格
    Console.SetCursorPosition(j * fill.Length, i);
    Console.BackgroundColor = ConsoleColor.White;
    Console.Write(fill);
}

private static void SetBlack(int i, int j)
{
    string fill = "  "; // 兩個空格
    Console.SetCursorPosition(j * fill.Length, i);
    Console.BackgroundColor = ConsoleColor.Black;
    Console.Write(fill);
}

 

至此,網格的創建和顯示就完成了,不過這兩個函數還沒有被調用。

在網格上繪制數字

現在網格可以通過update()函數顯示到控制台上了,接下來就可以對照那張excel表繪制指定的數字了。我用的這個繪制數字的方式是比較笨的,沒有想出來更好的辦法,如果有,歡迎在評論區指出。

繪制的基本方法就是把組成數字的格子設成白色,沒有數字的格子設成黑色,0到9一共10個數字全都繪制一遍。

先是一個枚舉,表示要繪制的數字開始的列,其中HourFirst表示“小時”的十位,開始於網格第1列,HourSecond表示“小時”的個位,開始於網格的第7列,依此類推。

public enum NumberLocation
{
    HourFirst = 1, HourSecond = 7,
    MinuteFirst = 15, MinuteSecond = 21,
    SecondFirst = 29, SecondSecond = 35,
}

 

下面是繪制代碼,因為太長就默認折疊了。其中TraverseNumber函數就是為了復用二重循環。DisplayNumber函數根據每個數字的坐標設置格子的Value值,location參數表示要顯示數字的列位置,接收一個枚舉,比如 DisplayNumber(3, NumberLocation.HourFirst) 表示“小時”的十位是3。

private static void DisplayNumber(int number, NumberLocation location)
{
    int colOffset = (int)location;
    switch (number)
    {
        case 0:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset || j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 1:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (j == colOffset + 4)
                {
                    grid[i, j].Value = true;
                    return;
                }

                grid[i, j].Value = false;
            });
            break;
        case 2:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                if (i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 3:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4 || i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 4:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 5)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 1 || i == 2 || i == 3 || i == 4)
                {
                    if (j == colOffset || j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                if (i == 6 || i == 7 || i == 8 || i == 9)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 5:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4)
                {
                    if (j == colOffset)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                if (i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 6:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4)
                {
                    if (j == colOffset)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                if (i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset || j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 7:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7 || i == 8 || i == 9)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 8:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4 || i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset || j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
        case 9:
            TraverseNumber(colOffset, (i, j) =>
            {
                if (i == 1 || i == 5 || i == 9)
                {
                    grid[i, j].Value = true;
                    return;
                }

                if (i == 2 || i == 3 || i == 4)
                {
                    if (j == colOffset || j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                if (i == 6 || i == 7 || i == 8)
                {
                    if (j == colOffset + 4)
                    {
                        grid[i, j].Value = true;
                        return;
                    }
                }

                grid[i, j].Value = false;
            });
            break;
    }
}
DisplayNumber

 

利用這個函數,就可以在控制台上顯示數字了,修改Main函數:

static void Main(string[] args)
{
    Init();

    DisplayNumber(1, NumberLocation.HourFirst);
    DisplayNumber(2, NumberLocation.HourSecond);
    DisplayNumber(3, NumberLocation.MinuteFirst);
    DisplayNumber(4, NumberLocation.MinuteSecond);
    DisplayNumber(5, NumberLocation.SecondFirst);
    DisplayNumber(6, NumberLocation.SecondSecond);

    Update();
}

 

 

但是現在只有數字,沒有分隔 小時 : 分鍾 : 秒 的那兩個小點。接下來繪制分隔點。首先定義枚舉類,確定分隔點所在的列:

public enum DotLocation
{
    First = 13, Second = 27
}

 

然后顯示分隔點:

private static void ShowAllDot()
{
    int firstCol = (int)DotLocation.First;
    int secondCol = (int)DotLocation.Second;

    grid[3, firstCol].Value = true;
    SetWhite(3, firstCol);
    grid[7, firstCol].Value = true;
    SetWhite(7, firstCol);

    grid[3, secondCol].Value = true;
    SetWhite(3, secondCol);
    grid[7, secondCol].Value = true;
    SetWhite(7, secondCol);
}

 

在Main函數中調用:

static void Main(string[] args)
{
    Init();

    DisplayNumber(1, NumberLocation.HourFirst);
    DisplayNumber(2, NumberLocation.HourSecond);
    DisplayNumber(3, NumberLocation.MinuteFirst);
    DisplayNumber(4, NumberLocation.MinuteSecond);
    DisplayNumber(5, NumberLocation.SecondFirst);
    DisplayNumber(6, NumberLocation.SecondSecond);

    ShowAllDot();
    Update();
}

 

運行看效果:

 

至此,數字和分隔點可以正常顯示了。

開始倒計時

 完成了設置數據和顯示數據的功能,就可以開始實現倒計時功能了。實現倒計時需要計時庫,C#提供了Stopwatch用來精確計時,我們就用這個類。

一開始先把倒計時的時間硬編碼,比如倒計時70秒,完成主要功能后再考慮讓用戶輸入。LeftTime函數將倒計時的總時間和經過的時間相減,再調用DisplayNumber修改網格的值。

修改Main函數。Main函數定義了倒計時時間,初始化網格,再定義Stopwatch變量,之后是一個無限循環。循環過程中用Stopwatch計時,如果經過時間大於倒計時總時間,則說明計時時間到。每次循環都調用Update函數來顯示數字:

static void Main(string[] args)
{
    int countdownSec = 70;

    Init();
    Stopwatch stopwatch = null;
    while (true)
    {
        if (stopwatch == null)
        {
            stopwatch = Stopwatch.StartNew();
        }

        // 時間到
        if (stopwatch != null && stopwatch.Elapsed.TotalSeconds > countdownSec)
        {
            LeftTime(countdownSec, countdownSec);
            stopwatch.Stop();
            stopwatch = null;

        }
        else
        {
            LeftTime(countdownSec, (int)stopwatch.Elapsed.TotalSeconds);
        }

        Update();
    }
}

private static void LeftTime(int countdownSec, int elapsedSec)
{
    var timeLeft = TimeSpan.FromSeconds(countdownSec - elapsedSec);
    DisplayNumber(timeLeft.Hours / 10, NumberLocation.HourFirst);
    DisplayNumber(timeLeft.Hours % 10, NumberLocation.HourSecond);
    DisplayNumber(timeLeft.Minutes / 10, NumberLocation.MinuteFirst);
    DisplayNumber(timeLeft.Minutes % 10, NumberLocation.MinuteSecond);
    DisplayNumber(timeLeft.Seconds / 10, NumberLocation.SecondFirst);
    DisplayNumber(timeLeft.Seconds % 10, NumberLocation.SecondSecond);
}

 

運行一下:

 

 可以看到計時器開始正常運行了。但是發現了一個問題,沒有分隔點。分隔點都是閃爍的,不是靜止的,所以需要添加一個切換分隔點狀態的函數,每次調用這個函數,分隔點都會切換顯示或隱藏的狀態:

private static void SwitchDot(DotLocation location)
{
    int colOffset = (int)location;
    if (grid[3, colOffset].Value)
    {
        grid[3, colOffset].Value = false;
        SetBlack(3, colOffset);
    }
    else
    {
        grid[3, colOffset].Value = true;
        SetWhite(3, colOffset);
    }

    if (grid[7, colOffset].Value)
    {
        grid[7, colOffset].Value = false;
        SetBlack(7, colOffset);
    }
    else
    {
        grid[7, colOffset].Value = true;
        SetWhite(7, colOffset);
    }
}

 

可以讓分隔點每500ms切換一次狀態,方法和倒計時的方法相同。為了不讓分隔點的計算影響倒計時的計算,需要單獨開一個線程。這里用Thread開線程,也可以用Task.Run開線程。修改Main函數:

static void Main(string[] args)
{
    int countdownSec = 70;

    Init();

    Thread dotThread = new Thread(() =>
    {
        ShowAllDot();

        Stopwatch dotWatch = null;
        while (true)
        {
            if (dotWatch == null)
            {
                dotWatch = Stopwatch.StartNew();
            }

            if (dotWatch.ElapsedMilliseconds >= 500)
            {
                SwitchDot(DotLocation.First);
                SwitchDot(DotLocation.Second);

                dotWatch.Stop();
                dotWatch = null;
            }
        }
    });
    dotThread.Start();

    Stopwatch stopwatch = null;
    while (true)
    {
        if (stopwatch == null)
        {
            stopwatch = Stopwatch.StartNew();
        }

        // 時間到
        if (stopwatch != null && stopwatch.Elapsed.TotalSeconds > countdownSec)
        {
            LeftTime(countdownSec, countdownSec);
            stopwatch.Stop();
            stopwatch = null;

        }
        else
        {
            LeftTime(countdownSec, (int)stopwatch.Elapsed.TotalSeconds);
        }

        Update();
    }
}

 

運行一下:

可以看到分隔點閃爍起來了。

但是現在的這個計時器不會停止,等計時完成后會重新開始,所以我們要讓計時完成時停止計時,並讓分隔點靜止。設置一個bool變量isCounting表示是否正在計時,為true表示正在計時,為false表示計時完畢。

修改Main函數:

static void Main(string[] args)
{
    int countdownSec = 5;

    Init();

    bool isCounting = true;

    Thread dotThread = new Thread(() =>
    {
        ShowAllDot();

        Stopwatch dotWatch = null;
        while (true)
        {
            if (dotWatch == null && isCounting)
            {
                dotWatch = Stopwatch.StartNew();
            }

            if (isCounting && dotWatch.ElapsedMilliseconds >= 500)
            {
                SwitchDot(DotLocation.First);
                SwitchDot(DotLocation.Second);

                dotWatch.Stop();
                dotWatch = null;
            }
        }
    });
    dotThread.Start();

    Stopwatch stopwatch = null;
    while (true)
    {
        if (stopwatch == null && isCounting)
        {
            stopwatch = Stopwatch.StartNew();
        }

        // 時間到
        if (stopwatch != null && stopwatch.Elapsed.TotalSeconds > countdownSec)
        {
            LeftTime(countdownSec, countdownSec);
            ShowAllDot();
            stopwatch.Stop();
            stopwatch = null;
            isCounting = false;
        }
        else if(isCounting)
        {
            LeftTime(countdownSec, (int)stopwatch.Elapsed.TotalSeconds);
        }

        Update();
    }
}

 

為了盡快看到效果,把計時總時間改為5秒。運行一下:

 

 可以看到計時完成之后數字不再改變,分隔點也靜止了。

至此,倒計時的主要功能就完成了。

用戶輸入

作為一個倒計時工具,把倒計時時間硬編碼肯定是不行的,需要讓用戶輸入,還有退出倒計時頁面、隱藏游標等功能。修改Main函數:

static void Main(string[] args)
{
    while (true)
    {
        Console.Clear();
        Console.CursorVisible = true;
        bool isQuit = false;
        bool isCounting = false;
        int countdownSec = 0;
        while (true)
        {
            Console.Write("Input Countdown Seconds: ");
            string countdownSecStr = Console.ReadLine();
            if (int.TryParse(countdownSecStr, out countdownSec))
            {
                break;
            }
        }

        Init();
        Console.CursorVisible = false;
        isCounting = true;

        Thread dotThread = new Thread(() =>
        {
            ShowAllDot();

            Stopwatch dotWatch = null;
            while (true)
            {
                if (isQuit)
                {
                    break;
                }

                if (dotWatch == null && isCounting)
                {
                    dotWatch = Stopwatch.StartNew();
                }

                if (isCounting && dotWatch.ElapsedMilliseconds >= 500)
                {
                    SwitchDot(DotLocation.First);
                    SwitchDot(DotLocation.Second);

                    dotWatch.Stop();
                    dotWatch = null;
                }
            }
        });
        dotThread.Start();

        Thread quitThread = new Thread(() =>
        {
            ConsoleKeyInfo key = Console.ReadKey();
            if (key.Key == ConsoleKey.Q)
            {
                isQuit = true;
            }
        });
        quitThread.Start();

        Stopwatch stopwatch = null;
        while (true)
        {
            if (isQuit)
            {
                break;
            }

            if (stopwatch == null && isCounting)
            {
                stopwatch = Stopwatch.StartNew();
            }

            // 時間到
            if (stopwatch != null && stopwatch.Elapsed.TotalSeconds > countdownSec)
            {
                LeftTime(countdownSec, countdownSec);
                ShowAllDot();
                stopwatch.Stop();
                stopwatch = null;
                isCounting = false;

            }
            else if (isCounting)
            {
                LeftTime(countdownSec, (int)stopwatch.Elapsed.TotalSeconds);
            }

            Update();
            Console.WriteLine("\n  Press q to quit");
        }
    }
}

 

最外層是一個無限循環,以保證程序不會自己退出。循環剛開始就接收用戶輸入的以秒為單位的總時間,之后初始化網格,隱藏游標,設置標志變量,開啟線程等。quitThread線程監聽用戶是否按了q鍵,是就退出倒計時頁面,返回到輸入頁面。

完整代碼

完整代碼將Main函數中的所有操作提取到了Countdown函數中,Main函數調用Countdown函數。

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Countdown
{
    class Program
    {
        private static Cell[,] grid = new Cell[11, 41];

        static void Main(string[] args)
        {
            Countdown();
        }

        private static void Countdown()
        {
            while (true)
            {
                Console.Clear();
                Console.CursorVisible = true;
                bool isQuit = false;
                bool isCounting = false;
                int countdownSec = 0;
                while (true)
                {
                    Console.Write("Input Countdown Seconds: ");
                    string countdownSecStr = Console.ReadLine();
                    if (int.TryParse(countdownSecStr, out countdownSec))
                    {
                        if (countdownSec > 86400)
                        {
                            continue;
                        }

                        break;
                    }
                }

                Init();
                Console.CursorVisible = false;
                isCounting = true;

                Thread dotThread = new Thread(() =>
                {
                    ShowAllDot();

                    Stopwatch dotWatch = null;
                    while (true)
                    {
                        if (isQuit)
                        {
                            break;
                        }

                        if (dotWatch == null && isCounting)
                        {
                            dotWatch = Stopwatch.StartNew();
                        }

                        if (isCounting && dotWatch.ElapsedMilliseconds >= 500)
                        {
                            SwitchDot(DotLocation.First);
                            SwitchDot(DotLocation.Second);

                            dotWatch.Stop();
                            dotWatch = null;
                        }
                    }
                });
                dotThread.Start();

                Thread quitThread = new Thread(() =>
                {
                    ConsoleKeyInfo key = Console.ReadKey();
                    if (key.Key == ConsoleKey.Q)
                    {
                        isQuit = true;
                    }
                });
                quitThread.Start();

                Stopwatch stopwatch = null;
                while (true)
                {
                    if (isQuit)
                    {
                        break;
                    }

                    if (stopwatch == null && isCounting)
                    {
                        stopwatch = Stopwatch.StartNew();
                    }

                    // 時間到
                    if (stopwatch != null && stopwatch.Elapsed.TotalSeconds > countdownSec)
                    {
                        LeftTime(countdownSec, countdownSec);
                        ShowAllDot();
                        stopwatch.Stop();
                        stopwatch = null;
                        isCounting = false;

                    }
                    else if (isCounting)
                    {
                        LeftTime(countdownSec, (int)stopwatch.Elapsed.TotalSeconds);
                    }

                    Update();
                    Console.WriteLine("\n  Press q to quit");
                }
            }
        }

        private static void LeftTime(int countdownSec, int elapsedSec)
        {
            var timeLeft = TimeSpan.FromSeconds(countdownSec - elapsedSec);
            DisplayNumber(timeLeft.Hours / 10, NumberLocation.HourFirst);
            DisplayNumber(timeLeft.Hours % 10, NumberLocation.HourSecond);
            DisplayNumber(timeLeft.Minutes / 10, NumberLocation.MinuteFirst);
            DisplayNumber(timeLeft.Minutes % 10, NumberLocation.MinuteSecond);
            DisplayNumber(timeLeft.Seconds / 10, NumberLocation.SecondFirst);
            DisplayNumber(timeLeft.Seconds % 10, NumberLocation.SecondSecond);
        }

        private static void Init()
        {
            for (int i = 0; i < grid.GetLength(0); i++)
            {
                for (int j = 0; j < grid.GetLength(1); j++)
                {
                    grid[i, j] = new Cell();
                    grid[i, j].Value = false;
                }
            }
        }

        private static void Update()
        {
            for (int i = 0; i < grid.GetLength(0); i++)
            {
                for (int j = 0; j < grid.GetLength(1); j++)
                {
                    if (grid[i, j].Value)
                    {
                        SetWhite(i, j);
                    }
                    else
                    {
                        SetBlack(i, j);
                    }
                }
            }
        }

        private static void SetWhite(int i, int j)
        {
            string fill = "  ";
            Console.SetCursorPosition(j * fill.Length, i);
            Console.BackgroundColor = ConsoleColor.White;
            Console.Write(fill);
        }

        private static void SetBlack(int i, int j)
        {
            string fill = "  ";
            Console.SetCursorPosition(j * fill.Length, i);
            Console.BackgroundColor = ConsoleColor.Black;
            Console.Write(fill);
        }

        private static void DisplayNumber(int number, NumberLocation location)
        {
            int colOffset = (int)location;
            switch (number)
            {
                case 0:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset || j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 1:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (j == colOffset + 4)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 2:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        if (i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 3:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4 || i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 4:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 5)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 1 || i == 2 || i == 3 || i == 4)
                        {
                            if (j == colOffset || j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        if (i == 6 || i == 7 || i == 8 || i == 9)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 5:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4)
                        {
                            if (j == colOffset)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        if (i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 6:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4)
                        {
                            if (j == colOffset)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        if (i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset || j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 7:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7 || i == 8 || i == 9)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 8:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4 || i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset || j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
                case 9:
                    TraverseNumber(colOffset, (i, j) =>
                    {
                        if (i == 1 || i == 5 || i == 9)
                        {
                            grid[i, j].Value = true;
                            return;
                        }

                        if (i == 2 || i == 3 || i == 4)
                        {
                            if (j == colOffset || j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        if (i == 6 || i == 7 || i == 8)
                        {
                            if (j == colOffset + 4)
                            {
                                grid[i, j].Value = true;
                                return;
                            }
                        }

                        grid[i, j].Value = false;
                    });
                    break;
            }
        }

        private static void TraverseNumber(int colOffset, Action<int, int> action)
        {
            for (int i = 1; i < 10; i++)
            {
                for (int j = colOffset; j < colOffset + 5; j++)
                {
                    action(i, j);
                }
            }
        }

        private static void SwitchDot(DotLocation location)
        {
            int colOffset = (int)location;
            if (grid[3, colOffset].Value)
            {
                grid[3, colOffset].Value = false;
                SetBlack(3, colOffset);
            }
            else
            {
                grid[3, colOffset].Value = true;
                SetWhite(3, colOffset);
            }

            if (grid[7, colOffset].Value)
            {
                grid[7, colOffset].Value = false;
                SetBlack(7, colOffset);
            }
            else
            {
                grid[7, colOffset].Value = true;
                SetWhite(7, colOffset);
            }
        }

        private static void ShowAllDot()
        {
            int firstCol = (int)DotLocation.First;
            int secondCol = (int)DotLocation.Second;

            grid[3, firstCol].Value = true;
            SetWhite(3, firstCol);
            grid[7, firstCol].Value = true;
            SetWhite(7, firstCol);

            grid[3, secondCol].Value = true;
            SetWhite(3, secondCol);
            grid[7, secondCol].Value = true;
            SetWhite(7, secondCol);
        }

        private static void HideAllDot()
        {
            int firstCol = (int)DotLocation.First;
            int secondCol = (int)DotLocation.Second;

            grid[3, firstCol].Value = false;
            SetBlack(3, firstCol);
            grid[7, firstCol].Value = false;
            SetBlack(7, firstCol);

            grid[3, secondCol].Value = false;
            SetBlack(3, secondCol);
            grid[7, secondCol].Value = false;
            SetBlack(7, secondCol);
        }
    }

    public class Cell
    {
        public bool Value { get; set; }
    }

    public enum NumberLocation
    {
        HourFirst = 1, HourSecond = 7,
        MinuteFirst = 15, MinuteSecond = 21,
        SecondFirst = 29, SecondSecond = 35,
    }

    public enum DotLocation
    {
        First = 13, Second = 27
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM