Newer
Older
NVTyping / WindowsFormsApplication1 / Form1.cs
@U-KWANSEI\ftp67940 U-KWANSEI\ftp67940 on 10 Oct 2017 11 KB initial release
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks; 
using System.Windows.Forms;

namespace NVTest
{
    public partial class NVType : Form
    {
        [System.Runtime.InteropServices.DllImport("winmm.dll")]
        private static extern int mciSendString(String command,
            StringBuilder buffer, int bufferSize, IntPtr hwndCallback);
        delegate int mciSendStringCallBack(string strCommand, 
            StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

        const string aliasName = "MediaFile";
        //const string prefix = "..\\..\\__output\\";
        const string prefix = "__output\\";

        int default_challenge = 60;
        bool game_start = false;
        DateTime start_time;
        DateTime[] score = new DateTime[1];
        char next_ans;
        int challenge_left;
        IDictionary<char, List<TimeSpan>> correct, mistake;
        System.Diagnostics.Stopwatch sw;

        public NVType()
        {
            InitializeComponent();
            KeyPreview = true;
            KeyPress += Form1_KeyPress1;
            FormClosing += NVType_FormClosing;
            correct = new Dictionary<char, List<TimeSpan>>();
            mistake = new Dictionary<char, List<TimeSpan>>();
            for (char c = 'a'; c <= 'z'; c++)
            {
                correct[c] = new List<TimeSpan>();
                mistake[c] = new List<TimeSpan>();
            }
            sw = new System.Diagnostics.Stopwatch();
        }

        private void NVType_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (talker_thread != null)
            {
                talker_thread.Abort();
            }
        }

        private void stopsound()
        {
            string cmd;
            cmd = "stop " + aliasName;
            mciSendString(cmd, null, 0, IntPtr.Zero);
            cmd = "close " + aliasName;
            mciSendString(cmd, null, 0, IntPtr.Zero);
        }

        private void stopsound_thread()
        {
            string cmd;
            cmd = "stop " + aliasName;
            invoke_thread(new object[] { cmd, null, 0, IntPtr.Zero });
            cmd = "close " + aliasName;
            invoke_thread(new object[] { cmd, null, 0, IntPtr.Zero });
        }

        private void playsound(string fileName, bool waitp = false)
        {
            stopsound();
            string cmd;

            //ファイルを開く
            cmd = "open \"" + fileName + "\" type mpegvideo alias " + aliasName;
            if (mciSendString(cmd, null, 0, IntPtr.Zero) != 0)
                return;
            //再生する
            cmd = "play " + aliasName;
            mciSendString(cmd, null, 0, IntPtr.Zero);
            if (waitp)
            {
                wait();
            }
        }

        private void playsound_thread(string fileName, bool waitp = false)
        {
            string cmd;
            int ret;
            stopsound_thread();
            //ファイルを開く
            cmd = "open \"" + fileName + "\" type mpegvideo alias " + aliasName;
            Console.WriteLine(cmd);
            ret = invoke_thread(new object[] { cmd, null, 0, IntPtr.Zero });
            if (ret != 0)
                return;
            //再生する
            cmd = "play " + aliasName;
            Console.WriteLine(cmd);
            ret = invoke_thread(new object[] { cmd, null, 0, IntPtr.Zero });
            if (waitp)
            {
                wait_thread();
            }
        }

        private int invoke_thread(object [] args)
        {
            int ret;
            if (InvokeRequired)
            {
                mciSendStringCallBack d = new mciSendStringCallBack(mciSendString);
                object e = this.Invoke(d, args);
                ret = (int)e;
            }
            else
            {
                ret = mciSendString((string)args[0], (StringBuilder) args[1], 
                    (int)args[2], (IntPtr)args[3]);
            }
            return ret;
        }

        private void wait_thread()
        {
            string cmd;
            StringBuilder buffer = new StringBuilder();
            int ret;
            do
            {
                cmd = "status " + aliasName + " mode";
                ret = invoke_thread(new object[] { cmd, buffer,30, IntPtr.Zero });
            } while (buffer.ToString() == "playing");
        }
 
        private void wait()
        {
            string cmd;
            StringBuilder ret = new StringBuilder();
            do
            {
                cmd = "status " + aliasName + " mode";
                mciSendString(cmd, ret, 30, IntPtr.Zero);
            } while (ret.ToString() == "playing");
        }

        private void number(int a)
        {
            string fileName;
            double digits = (int)Math.Log10(a);
            int div;
            while (a > 0)
            {
                div = (int)Math.Pow(10, digits);
                fileName = prefix + (a / div).ToString() + ".mp3";
                if (digits == 0 || a / div != 1)
                    playsound(fileName, true);
                if (digits == 2)
                {
                    playsound(prefix + "100.mp3", true);
                }
                else if (digits == 1)
                {
                    playsound(prefix + "10.mp3", true);
                }
                a -= (a / div) * div;
                digits--;
            }
        }

        private void greeting()
        {
            playsound_thread(prefix + "opening.mp3", true);
            playsound_thread(prefix + "description.mp3", true);
            playsound_thread(prefix + "hitanykey.mp3", true);
        }

        private void dictate(char f)
        {
            string filename = prefix + f + ".mp3";
            playsound(filename);
        }

        private void setup()
        {
            Random rnd = new Random();
                      //12345678901234567890123456
            char new_ans;
            do
            {
                new_ans = "abcdefghijklmnopqrstuvwxyz"[rnd.Next(26)];
            } while (next_ans == new_ans);
            next_ans = new_ans;

            label1.Text = next_ans.ToString().ToUpper();
            dictate(next_ans);
            sw.Reset();
            sw.Start();
        }
        public enum MessageBeepType : int
        {
            SimpleBeep = -1,
            MB_OK = 0x00,
            MB_ICONHAND = 0x10,
            MB_ICONQUESTION = 0x20,
            MB_ICONEXCLAMATION = 0x30,
            MB_ICONASTERISK = 0x40,
        }

        private void write_log(int sec)
        {
            System.IO.StreamWriter f = new System.IO.StreamWriter("record.txt", true, Encoding.UTF8);
            DateTime d = DateTime.Now;

            f.WriteLine(d.ToString() + "\t" + sec.ToString() + "秒");
            f.Close();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool MessageBeep(MessageBeepType uType);
        private void Form1_KeyPress1(object sender, KeyPressEventArgs e)
        {
            if (talker_thread != null)
            {
                talker_thread.Abort();
            }

            if (game_start)
            {
                if (e.KeyChar == '\x1b')
                {
                    label1.Text = "!";
                    game_start = false;
                    indicator2.Text = "--";
                    talker_thread = new System.Threading.Thread(
                        new System.Threading.ThreadStart(greeting));
                    talker_thread.Start();
                }

                if (e.KeyChar == next_ans)
                { //pinpon
                    sw.Stop();
                    correct[next_ans].Add(sw.Elapsed);
                    MessageBeep(MessageBeepType.MB_ICONASTERISK);
                    challenge_left--;
                    indicator2.Text = (default_challenge-challenge_left+1).ToString();
                    setup();
                } else
                {
                    mistake[next_ans].Add(sw.Elapsed);
                    dictate(next_ans);
                    sw.Reset();
                    sw.Start();
                }
                if (challenge_left == 0) {
                    game_start = false; label1.Text = "!";

                    TimeSpan ts = DateTime.Now - start_time;
                    int sec = ts.Minutes * 60 + ts.Seconds;
                    label2.Text = sec.ToString() + "秒";
                    write_log(sec);
                    number(sec);
                    playsound(prefix + "seconds.mp3", true);
                    Console.WriteLine(sec);

                    if (sec > 60)
                    {
                        playsound(prefix + "sorry.mp3", true);
                    }
                    else
                    {
                        playsound(prefix + "congra.mp3", true);
                    }

                    double sum = 0; int n = 0;
                    for (char c = 'a'; c <= 'z'; c++)
                    {
                        foreach (var item in correct[c])
                        {
                            sum += item.TotalSeconds;
                            n++;
                        }
                        foreach (var item in mistake[c])
                        {
                            sum += item.TotalSeconds;
                            n++;
                        }
                    }
                    label3.Text = "平均:" + (sum / n).ToString("F") + "s";

                    System.Threading.Thread.Sleep(1000);
                    indicator2.Text = "--";
                    talker_thread = new System.Threading.Thread(
                        new System.Threading.ThreadStart(greeting));
                    talker_thread.Start();
                }
            }
            else
            {
                if (e.KeyChar == '\x1b')
                {
                    Close();
                }

                if (e.KeyChar == ' ')
                {
                    game_start = true; start_time = DateTime.Now; challenge_left = default_challenge;
                    Console.WriteLine("OK start"); setup(); indicator2.Text = "1";
                    label2.Text = "";

                }
                else if (e.KeyChar == '+')
                {
                    default_challenge++;
                    indicator1.Text= default_challenge.ToString();
                }
                else if (e.KeyChar == '-')
                {
                    default_challenge--;
                    indicator1.Text = default_challenge.ToString();
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }
        System.Threading.Thread talker_thread;
        private void Form1_Shown(object sender, EventArgs e)
        {
            talker_thread = new System.Threading.Thread(
                new System.Threading.ThreadStart(greeting));
            talker_thread.Start();
        }

        private void NVType_Resize(object sender, EventArgs e)
        {
            Control c = (Control)sender;
            int w = c.Width < c.Height ? c.Width : c.Height;
            label1.Font = new Font("MS UI Gothic", w *5 / 6);
        }
    }
}