/Vanilla/ConsoleIO.cs

https://github.com/caphindsight/TrulyQuantumChess · C# · 180 lines · 168 code · 12 blank · 0 comment · 37 complexity · 866548d6f5fbd52f20eeee2de8bf7a20 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text.RegularExpressions;
  4. using TrulyQuantumChess.Kernel.Errors;
  5. using TrulyQuantumChess.Kernel.Moves;
  6. using TrulyQuantumChess.Kernel.Chess;
  7. using TrulyQuantumChess.Kernel.Quantize;
  8. using TrulyQuantumChess.Kernel.Engine;
  9. namespace TrulyQuantumChess.Vanilla.ConsoleIO {
  10. public static class Input {
  11. public static QuantumChessMove ReadMove(QuantumChessEngine engine) {
  12. switch (engine.ActivePlayer) {
  13. case Player.White:
  14. Console.Write("white> ");
  15. break;
  16. case Player.Black:
  17. Console.Write("black> ");
  18. break;
  19. }
  20. string move_str = Console.ReadLine();
  21. string capitulate_move_regex = @"^(quit|exit|capitulate)$";
  22. string agree_to_tie_move_regex = @"^tie$";
  23. string ordinary_move_regex = @"^([A-Za-z][1-8])\s*([A-Za-z][1-8])$";
  24. string quantum_move_regex = @"^(?:q|Q|quantum)\s+([A-Za-z][1-8])\s*((?:[A-Za-z][1-8])?)\s*([A-Za-z][1-8])$";
  25. string castle_move_regex = @"^castle (left|right)$";
  26. Match ordinary_match = Regex.Match(move_str, ordinary_move_regex);
  27. Match quantum_match = Regex.Match(move_str, quantum_move_regex);
  28. Match castle_match = Regex.Match(move_str, castle_move_regex);
  29. if (Regex.IsMatch(move_str, capitulate_move_regex)) {
  30. return new CapitulateMove(engine.ActivePlayer);
  31. } else if (Regex.IsMatch(move_str, agree_to_tie_move_regex)) {
  32. return new AgreeToTieMove(engine.ActivePlayer);
  33. } else if (ordinary_match.Success) {
  34. Position source = Position.Parse(ordinary_match.Groups[1].Captures[0].Value);
  35. Position target = Position.Parse(ordinary_match.Groups[2].Captures[0].Value);
  36. QuantumPiece qpiece = engine.QuantumChessboard.GetQuantumPiece(source);
  37. if (qpiece.Piece.HasValue)
  38. return new OrdinaryMove(qpiece.Piece.Value, source, target);
  39. else
  40. throw new MoveParseException($"No piece found at {source}");
  41. } else if (quantum_match.Success) {
  42. Position source = Position.Parse(quantum_match.Groups[1].Captures[0].Value);
  43. Position? middle = null;
  44. if (quantum_match.Groups[2].Captures[0].Length > 0)
  45. middle = Position.Parse(quantum_match.Groups[2].Captures[0].Value);
  46. Position target = Position.Parse(quantum_match.Groups[3].Captures[0].Value);
  47. QuantumPiece qpiece = engine.QuantumChessboard.GetQuantumPiece(source);
  48. if (qpiece.Piece.HasValue)
  49. return new QuantumMove(qpiece.Piece.Value, source, middle, target);
  50. else
  51. throw new MoveParseException($"No piece found at {source}");
  52. } else if (castle_match.Success) {
  53. string castle_type_str = castle_match.Groups[1].Captures[0].Value;
  54. CastleType castle_type;
  55. if (castle_type_str == "left") {
  56. castle_type = CastleType.Left;
  57. } else if (castle_type_str == "right") {
  58. castle_type = CastleType.Right;
  59. } else {
  60. throw new MoveParseException($"Unsupported castle type: {castle_type_str}");
  61. }
  62. return new CastleMove(engine.ActivePlayer, castle_type);
  63. } else {
  64. throw new MoveParseException("Unable to parse move");
  65. }
  66. }
  67. public static QuantumChessMove ReadMoveRepeated(QuantumChessEngine engine) {
  68. for (;;) {
  69. try {
  70. return ReadMove(engine);
  71. } catch (MoveParseException e) {
  72. Console.WriteLine(e.Message);
  73. }
  74. }
  75. }
  76. }
  77. public static class Output {
  78. private static char GetUnicodeChar(Piece? piece) {
  79. if (piece.HasValue) {
  80. switch (piece.Value.Player) {
  81. case Player.White:
  82. switch (piece.Value.PieceType) {
  83. case PieceType.Pawn: return '\u2659';
  84. case PieceType.Knight: return '\u2658';
  85. case PieceType.Bishop: return '\u2657';
  86. case PieceType.Rook: return '\u2656';
  87. case PieceType.Queen: return '\u2655';
  88. case PieceType.King: return '\u2654';
  89. default: throw new AssertionException($"Unsupported piece type: {piece.Value.PieceType}");
  90. }
  91. case Player.Black:
  92. switch (piece.Value.PieceType) {
  93. case PieceType.Pawn: return '\u265F';
  94. case PieceType.Knight: return '\u265E';
  95. case PieceType.Bishop: return '\u265D';
  96. case PieceType.Rook: return '\u265C';
  97. case PieceType.Queen: return '\u265B';
  98. case PieceType.King: return '\u265A';
  99. default: throw new AssertionException($"Unsupported piece type: {piece.Value.PieceType}");
  100. }
  101. default:
  102. throw new AssertionException($"Unsupported player: {piece.Value.Player}");
  103. }
  104. } else {
  105. return '.';
  106. }
  107. }
  108. private static void DisplayHarmonics(List<QuantumHarmonic> harmonics) {
  109. for (int y = 7; y >= 0; y--) {
  110. foreach (QuantumHarmonic harmonic in harmonics) {
  111. Console.Write($"{y+1} ");
  112. for (int x = 0; x < 8; x++) {
  113. Console.Write(GetUnicodeChar(harmonic.Board[x, y]));
  114. Console.Write(" ");
  115. }
  116. Console.Write(" ");
  117. }
  118. Console.WriteLine();
  119. }
  120. foreach (QuantumHarmonic harmonic in harmonics) {
  121. Console.Write(" a b c d e f g h ");
  122. }
  123. Console.WriteLine();
  124. foreach (QuantumHarmonic harmonic in harmonics) {
  125. string win_str;
  126. switch (harmonic.Board.GameState) {
  127. case GameState.GameStillGoing:
  128. win_str = " ";
  129. break;
  130. case GameState.WhiteVictory:
  131. win_str = "[w]";
  132. break;
  133. case GameState.BlackVictory:
  134. win_str = "[b]";
  135. break;
  136. case GameState.Tie:
  137. win_str = "[=]";
  138. break;
  139. default:
  140. throw new AssertionException($"Unsupported game state: {harmonic.Board.GameState}");
  141. }
  142. string deg = harmonic.Degeneracy == 1 ? " " : $"x{harmonic.Degeneracy}";
  143. Console.Write($" {win_str} {deg}");
  144. int expected_ln = 8;
  145. int actual_ln = harmonic.Degeneracy.ToString().Length;
  146. for (int i = actual_ln; i != expected_ln; i++)
  147. Console.Write(" ");
  148. Console.Write(" ");
  149. }
  150. Console.WriteLine();
  151. }
  152. public static void DisplayQuantumChessboard(QuantumChessboard qboard, int cols) {
  153. int n = qboard.Harmonics.Count;
  154. int rows = (n + cols - 1) / cols;
  155. for (int row = 0; row < rows; row++) {
  156. var harmonics = new List<QuantumHarmonic>();
  157. for (int col = 0; col < cols; col++) {
  158. int ind = row * cols + col;
  159. if (ind < n)
  160. harmonics.Add(qboard.Harmonics[ind]);
  161. }
  162. DisplayHarmonics(harmonics);
  163. if (row != rows - 1)
  164. Console.WriteLine();
  165. }
  166. }
  167. }
  168. }