質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2821閲覧

C#コンソールアプリでタイピング練習アプリの改良

yulico

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/04/08 00:42

前提・実現したいこと

C# コンソールアプリでタイピング練習アプリを作っています。

ほぼ完成していますが、改良のヒントを得たくて投稿しました。

ゲームの流れは下記の通り
・英単語が横位置(範囲80文字)ランダムで、一定時間毎に1行ずつ落ちていく。
・キー入力を始めると、正しい文字であれば、一文字ずつ'*'(アスタリスク)に変わる。
・全て正しく入力されれば、スコアカウントされ、次の英単語に移る。
・入力を間違えるか、再下段まで行くと、ミスカウントされ、次の英単語に移る。

キー入力始めの時に英単語が落ちなくなる(ReadKeyによるブロック)のを防ぎたいです。
(英単語が常に一定時間で落ちながら、正しい文字を入力したらそのタイミングで、'*'に変わっていくようにしたい)

english → 下の行に落ちるまでに、正しく3文字入力出来たら
***lish → となって落ちていく

該当のソースコード

C#

1using System; 2 3namespace typ 4{ 5 class Program 6 { 7 static int level = 0; 8 static int score = 0; 9 static int miss = 0; 10 11 static int typing() 12 { 13 string[] word = new string[] { "english", "japanese", "french", "spanish", "hoge", "fuga" }; 14 15 Console.Clear(); 16 17 Console.ForegroundColor = ConsoleColor.Yellow; 18 Console.Write(" Typing of Fall Down Text "); 19 Console.ForegroundColor = ConsoleColor.White; 20 Console.WriteLine("Score {0} Miss {1}", score.ToString("000"), miss.ToString("000")); 21 Console.ForegroundColor = ConsoleColor.Gray; 22 Console.WriteLine(new string('-', 80)); 23 Console.SetCursorPosition(0, 22); 24 Console.WriteLine(new string('-', 80)); 25 26 int s = Environment.TickCount; 27 28 Random rnd = new Random(s++); 29 30 int r = rnd.Next(60); 31 int c = rnd.Next(word.Length); 32 33 for (int l = 2; l < 22; l++) 34 { 35 int wait = word[c].Length + (1050 - level * 180); 36 37 if (Console.KeyAvailable) 38 { 39 for (int i = 0; i < word[c].Length; i++) 40 { 41 if (word[c].Substring(i, 1) != "*") 42 { 43 if (Console.ReadKey(true).Key.ToString() == word[c].Substring(i, 1).ToUpper()) 44 { 45 word[c] = word[c].Substring(0, i) + "*" + word[c].Substring(i + 1, word[c].Length - (i + 1)); 46 47 if (l > 2) 48 { 49 Console.SetCursorPosition(0, l - 1); 50 Console.Write(new string(' ', 80)); 51 } 52 53 Console.SetCursorPosition(r, l); 54 Console.ForegroundColor = ConsoleColor.Green; 55 Console.Write(word[c]); 56 Console.ForegroundColor = ConsoleColor.Gray; 57 58 continue; 59 } 60 else if (Console.ReadKey(true).Key == ConsoleKey.Escape) 61 { 62 Console.Clear(); 63 64 return 1; 65 } 66 else 67 { 68 Console.SetCursorPosition(44, 0); 69 Console.ForegroundColor = ConsoleColor.White; 70 Console.WriteLine((++miss).ToString("000")); 71 Console.ForegroundColor = ConsoleColor.Gray; 72 73 return 0; 74 } 75 } 76 } 77 } 78 else 79 { 80 if (l > 2) 81 { 82 Console.SetCursorPosition(0, l - 1); 83 Console.Write(new string(' ', 80)); 84 } 85 86 Console.SetCursorPosition(r, l); 87 Console.ForegroundColor = ConsoleColor.Green; 88 Console.Write(word[c]); 89 Console.ForegroundColor = ConsoleColor.Gray; 90 91 if (word[c] == new string('*', word[c].Length)) 92 { 93 Console.SetCursorPosition(36, 0); 94 Console.ForegroundColor = ConsoleColor.White; 95 Console.WriteLine((++score).ToString("000")); 96 Console.ForegroundColor = ConsoleColor.Gray; 97 98 break; 99 } 100 101 System.Threading.Thread.Sleep(wait); 102 } 103 } 104 105 Console.Clear(); 106 107 return 0; 108 } 109 110 static void Main(string[] args) 111 { 112 Console.Write("Level(1 - 5) = "); 113 114 string lv = Console.ReadLine(); 115 116 level = int.Parse(lv); 117 118 if (level < 1) level = 1; 119 else if (level > 5) level = 5; 120 121 while (true) 122 { 123 if (typing() == 1) break; 124 } 125 } 126 } 127}

補足情報

Microsoft Visual Studio Community 2019
Version 16.5.0
.NET Framework version 4.8.03761

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/04/08 01:00

Console.KeyAvailable が true の場合、キーバッファにキー入力がたまっているので、Console.ReadKey はすぐに処理を戻します。その結果、キーバッファが空になれば KeyAvailable は false を返します。これが true の時だけキーを読めばいいと思います。
yulico

2020/04/08 02:15

ありがとうございます。 KeyAvailable が true の時だけキーを読むようにしてみます。 ありがとうございました。
guest

回答1

0

ベストアンサー

Console.KeyAvailableプロパティを利用して、キー入力があった時のみReadKeyしてはどうでしょうか

よくよくソースを見たら、
正しいキーを押した場合はReadKeyを1回しか実行しないので問題はないのですが、間違ったキーを押した場合、elseifにてもう一回ReadKeyが呼ばれ、そこでブロックしているのではないですか?

KeyAvailableプロパティにてキー入力があったと判断した後、ReadKeyを一旦変数で受けて、その変数を利用して、その後の判断を行うようにすればよろしいかと思います。

投稿2020/04/08 00:50

編集2020/04/08 01:11
YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yulico

2020/04/08 01:00

早い回答、ありがとうございます。 >Console.KeyAvailableプロパティを利用して、キー入力があった時のみReadKeyしてはどうでしょうか やっているつもりなのですが、場所が悪いのでしょうか・・・ 見直してみます。
YAmaGNZ

2020/04/08 01:04

KeyAvailableにて入力があったと判断した後にReadKeyを複数回呼ぶような形になっています。 ですので、キー入力があったと判断した後、ReadKeyの結果を一旦変数に受け取り、その変数の値で比較処理を行うべきです。
yulico

2020/04/08 01:27

ああ、確かにループさせてしまってますね(^^;; 変数処理に直してみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問