public void ShouldThrowInvalidMoveExceptionIfCellIsAlreadyRevealed() { var revealedCoordinate = new Coordinate(1, 1); _gameBoard.GetCell(revealedCoordinate).CellState = CellState.Revealed; var flagCommand = new FlagCommand(revealedCoordinate); Assert.Throws <InvalidMoveException>(() => flagCommand.Execute(_gameBoard)); }
public void ShouldSetSelectedCellStateToFlagged() { var flagCoordinate = new Coordinate(1, 1); var flagCommand = new FlagCommand(flagCoordinate); flagCommand.Execute(_gameBoard); var result = _gameBoard.GetCell(flagCoordinate).CellState; Assert.Equal(CellState.Flagged, result); }
public void ShouldSetCellStateToUnrevealedIfAlreadyFlagged() { var flagCoordinate = new Coordinate(1, 1); _gameBoard.GetCell(flagCoordinate).CellState = CellState.Flagged; var flagCommand = new FlagCommand(flagCoordinate); flagCommand.Execute(_gameBoard); var result = _gameBoard.GetCell(flagCoordinate).CellState; Assert.Equal(CellState.Unrevealed, result); }
public void ShouldThrowInvalidMoveException_IfTyringToFlagMoreFlagsThanMines() { // Plant 2 mines _gameBoard.GetCell(new Coordinate(4, 4)).PlantMine(); _gameBoard.GetCell(new Coordinate(5, 5)).PlantMine(); // Flag 2 cells that aren't mines _gameBoard.GetCell(new Coordinate(2, 2)).CellState = CellState.Flagged; _gameBoard.GetCell(new Coordinate(1, 1)).CellState = CellState.Flagged; // Flagging the third cell var flagCommand = new FlagCommand(new Coordinate(4, 4)); Assert.Throws <InvalidMoveException>(() => flagCommand.Execute(_gameBoard)); }
public override float SeekTo(float time) { int newcusor = CurrentCusor; //从中间刻度修正当前状态 void FixMidLine() { LineCommand curLine = commandList.Values[CurrentCusor].GetLineCommand(); bool[] arr = (bool[])curLine.enter_group_status.Clone(); bool[] arr_trans = (bool[])curLine.enter_group_status_translate.Clone(); { //回溯已经激活的组信息 int temp = CurrentCusor; while (commandList.Values[temp] != curLine) { GroupCommand group = (GroupCommand)commandList.Values[temp]; foreach (var gp in group.gpList) { if (gp.isTranslate) { arr_trans[gp.id] = true; } else { arr[gp.id] = true; } } temp--; } OnActiveLyricLine?.Invoke(new LineInfoBundle() { LyricLine = curLine.line, LineNumber = curLine.linecode, GroupActiveInfo = arr, TranslateActiveInfo = arr_trans }); } } if (CurrentCusor < 0 || commandList.Keys[CurrentCusor] < time) { //CorrentCusor++ while (newcusor + 1 < commandList.Count && commandList.Keys[newcusor + 1] <= time) { newcusor++; } if (newcusor > CurrentCusor) { //now turn to newcusor //CurrentCusor may equals -1 if (CurrentCusor != newcusor - 1) { //需要重置状态 while (CurrentCusor + 1 < newcusor) { FlagCommand ncmd = commandList.Values[CurrentCusor + 1]; if (ncmd is LineCommand) { if (CurrentCusor != -1) { //DeActive CurrentCusor as exit status LineCommand lcmd = commandList.Values[CurrentCusor].GetLineCommand(); OnUnActiveLyricLine?.Invoke(new LineInfoBundle() { LyricLine = lcmd.line, LineNumber = lcmd.linecode, GroupActiveInfo = lcmd.exit_group_status, TranslateActiveInfo = lcmd.exit_group_status_translate }); } } CurrentCusor++; }//while(CurrentCusor + 1< newcusor) if (commandList.Values[newcusor] is GroupCommand) { //现在位于行中间,回溯激活当前行 FixMidLine(); } } //现在CurrentCusor == newcusor - 1了,而且状态正常 //下一行是Line,则UnActive当前Line,并Active下一行的Line,下一行是Group,则Active这个Line,并激活Group if (commandList.Values[newcusor] is GroupCommand) { //激活新Group CurrentCusor++; LineCommand curLine = commandList.Values[CurrentCusor].GetLineCommand(); //assert CurrentCusor == newcusor foreach (var x in ((GroupCommand)commandList.Values[CurrentCusor]).gpList) { OnActiveGroup?.Invoke(new GroupInfoBundle() { Group = x.group, GroupId = x.id, IsTranslate = x.isTranslate, LineNumber = curLine.linecode, LyricLine = curLine.line }); } } else {//下面是新的一行(正常换行走这里),UnActive当前行并激活新行 if (CurrentCusor >= 0) { LineCommand lcmd = commandList.Values[CurrentCusor].GetLineCommand(); OnUnActiveLyricLine?.Invoke(new LineInfoBundle() { LyricLine = lcmd.line, LineNumber = lcmd.linecode, GroupActiveInfo = lcmd.exit_group_status, TranslateActiveInfo = lcmd.exit_group_status_translate }); } CurrentCusor++; {//Active new line LineCommand lcmd = (LineCommand)commandList.Values[CurrentCusor]; OnActiveLyricLine?.Invoke(new LineInfoBundle() { LyricLine = lcmd.line, LineNumber = lcmd.linecode, GroupActiveInfo = lcmd.enter_group_status, TranslateActiveInfo = lcmd.enter_group_status_translate }); } } } //CurrentCusor ++ end } else { //CurrentCusor-- or keep while (newcusor >= 0 && commandList.Keys[newcusor] > time) { newcusor--; } if (newcusor < CurrentCusor) { //new turn to newcusor //newcusor may equals -1 while (newcusor < CurrentCusor) { if (commandList.Values[CurrentCusor] is LineCommand) { //UnActinve this line and all group LineCommand lcmd = (LineCommand)commandList.Values[CurrentCusor]; OnUnActiveLyricLine?.Invoke(new LineInfoBundle() { LineNumber = lcmd.linecode, LyricLine = lcmd.line, GroupActiveInfo = null,//传值全false TranslateActiveInfo = null }); } CurrentCusor--; } //回溯当前行 if (CurrentCusor >= 0) { FixMidLine(); } } //CurrentCusor-- end } if (CurrentCusor + 1 < commandList.Count) { return(commandList.Keys[CurrentCusor + 1]); } else { return(float.PositiveInfinity); } }
public static Command Parse(string input) { string[] values = input.Split(' '); if (!values.Any()) { throw new ArgumentException("No command specified."); } // command should be first if (!Enum.TryParse(values[0].ToPascalCase(), out CommandType type)) { throw new ArgumentException($"Invalid command {values[0]}"); } if (type == CommandType.Undefined) { throw new ArgumentException($"Invalid command {type}"); } string[] args = values.Skip(1).ToArray(); Command command = null; switch (type) { case CommandType.End: { command = new EndCommand(); break; } case CommandType.Flag: { command = new FlagCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length != requiredArgs.Count) { throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments."); } if (!int.TryParse(args[0], out int x)) { throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer."); } if (!int.TryParse(args[1], out int y)) { throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer."); } requiredArgs[CommandKeys.XPosition] = x; requiredArgs[CommandKeys.YPosition] = y; command.Build(requiredArgs); break; } case CommandType.Help: { command = new HelpCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length > 0) { if (args.Length > 1) { throw new ArgumentException($"Command type {type} requires 1 or 0 arguments."); } if (!Enum.TryParse(args[0].ToPascalCase(), out CommandType commandType)) { throw new ArgumentException($"Invalid command type {args[0]}"); } requiredArgs[CommandKeys.CommandName] = commandType; command.Build(requiredArgs); } break; } case CommandType.New: { command = new NewCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length != requiredArgs.Count) { throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments."); } if (!int.TryParse(args[0], out int x)) { throw new ArgumentException($"Parameter {CommandKeys.XLength} must be an integer."); } if (!int.TryParse(args[1], out int y)) { throw new ArgumentException($"Parameter {CommandKeys.YLength} must be an integer."); } if (!int.TryParse(args[2], out int b)) { throw new ArgumentException($"Parameter {CommandKeys.Bombs} must be an integer."); } requiredArgs[CommandKeys.XLength] = x; requiredArgs[CommandKeys.YLength] = y; requiredArgs[CommandKeys.Bombs] = b; command.Build(requiredArgs); break; } case CommandType.Open: { command = new OpenCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length != requiredArgs.Count) { throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments."); } if (!int.TryParse(args[0], out int x)) { throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer."); } if (!int.TryParse(args[1], out int y)) { throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer."); } requiredArgs[CommandKeys.XPosition] = x; requiredArgs[CommandKeys.YPosition] = y; command.Build(requiredArgs); break; } case CommandType.Quit: { command = new QuitCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); break; } case CommandType.Unflag: { command = new UnflagCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length != requiredArgs.Count) { throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments."); } if (!int.TryParse(args[0], out int x)) { throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer."); } if (!int.TryParse(args[1], out int y)) { throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer."); } requiredArgs[CommandKeys.XPosition] = x; requiredArgs[CommandKeys.YPosition] = y; command.Build(requiredArgs); break; } case CommandType.Status: { command = new StatusCommand(); Dictionary <string, object> requiredArgs = command.GetRequiredArguments(); if (args.Length != requiredArgs.Count) { throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments."); } if (!int.TryParse(args[0], out int x)) { throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer."); } if (!int.TryParse(args[1], out int y)) { throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer."); } requiredArgs[CommandKeys.XPosition] = x; requiredArgs[CommandKeys.YPosition] = y; command.Build(requiredArgs); break; } } return(command); }
public List<Square> Update(FlagCommand command, PlayerState player) { var square = _squares[command.Index]; var changed = new List<Square>(); if (square.Revealed || square.Flagged) { } else if (square.Mined) { square.Flagged = true; square.Revealed = true; square.Owner = player.Hash; changed.Add(square); player.Points++; LiveBombs--; } else { player.Dead = true; } return changed; }