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);
}
}
}