private void RemoveCapturedPieces(GoMoveResponse resp) { foreach (var piece in Pieces.Values) { if (piece.IsNewCapture) { piece.IsNewCapture = false; piece.RaiseMultiplePropertiesChanged(); } } foreach (var capturedPosition in resp.MoveResult.CapturedStones.Split(' ')) { if (!String.IsNullOrWhiteSpace(capturedPosition)) { if (Pieces.ContainsKey(capturedPosition)) { var piece = Pieces[capturedPosition]; piece.Color = null; piece.IsNewCapture = true; piece.RaiseMultiplePropertiesChanged(); } } } }
public async void ExecutePressedCommand(string position) { // Note: position is the Go position such as "A15" where the user pressed. if (!Pieces.ContainsKey(position)) { return; } _savedColor = Pieces[position].Color; Pieces[position].Color = _players[WhoseTurn].Color; Pieces[position].RaiseMultiplePropertiesChanged(); MessageText = "Moving..."; IsBusy = true; var move = new GoMove(MoveType.Normal, _players[WhoseTurn].Color, position); GoMoveResponse resp = await DataRepository.PlayAsync(ActiveGame, move); IsBusy = false; MessageText = null; if (resp.ResultCode == GoResultCode.Success) { AddMoveToHistory(resp.Move, resp.MoveResult); //Pieces[resp.Move.Position].IsNewPiece = true; RemoveCapturedPieces(resp); CurrentPlayer.Prisoners += resp.MoveResult.CapturedStones.Split(' ').Count(x => x != String.Empty); Pieces[position].RaiseMultiplePropertiesChanged(); SwapTurns(); SetState(resp.MoveResult.Status, resp.MoveResult.WinMargin); if (Status == GoGameStatus.Active) { PlayCurrentUser(); } } else if (resp.ResultCode == GoResultCode.CommunicationError) { await HandleCommunicationError("Moving..."); } else { Pieces[position].Color = _savedColor; Pieces[position].RaiseMultiplePropertiesChanged(); await DisplayErrorCode(resp.ResultCode); } RaiseCommandsChanged(); }
public GoMoveResponse Play(Guid gameid, GoMove move) { GoMoveResponse rval; try { var result = FuegoEngine.Instance.Play(gameid, move); rval = new GoMoveResponse(GoResultCode.Success, move, result); } catch (GoEngineException gex) { _logger.LogEngineException(gameid, gex, move); rval = new GoMoveResponse(gex.Code, null, null); } catch (Exception ex) { _logger.LogServerError(gameid, ex, move); rval = new GoMoveResponse(GoResultCode.ServerInternalError, null, null); } return(rval); }
public GoMoveResponse GenMove(Guid gameid, GoColor color) { GoMoveResponse rval; try { GoMove newMove; GoMoveResult result; FuegoEngine.Instance.GenMove(gameid, color, out newMove, out result); rval = new GoMoveResponse(GoResultCode.Success, newMove, result); } catch (GoEngineException gex) { _logger.LogEngineException(gameid, gex, color); rval = new GoMoveResponse(gex.Code, null, null); } catch (Exception ex) { _logger.LogServerError(gameid, ex, color); rval = new GoMoveResponse(GoResultCode.ServerInternalError, null, null); } return(rval); }
public async Task <GoMoveResponse> PlayAsync(Guid id, GoMove move) { await LoadState(); GoMoveResponse rval = null; GoMoveResult moveResult; try { await Task.Run( async() => { await EnsureFuegoStartedAndMatchingGame(id); if (move.MoveType == MoveType.Resign) { // Fuego doesn't support the command to resign. _state.Operation = GoOperation.Resign; moveResult = AddMoveAndUpdateState(move); await SaveState(); } else { string position; switch (move.MoveType) { case MoveType.Normal: position = move.Position; _state.Operation = GoOperation.NormalMove; break; case MoveType.Pass: position = "PASS"; _state.Operation = GoOperation.Pass; break; default: throw new ArgumentException("Unrecognized move type: " + move.MoveType); } // This throws a GoEngineException on any failure. ParseResponse(WriteCommand("play", (move.Color == GoColor.Black ? "black" : "white") + ' ' + position)); // Add to move history and persist new game state so user can // see what happened. moveResult = AddMoveAndUpdateState(move); _state.Operation = GoOperation.Idle; await SaveState(); } Debug.Assert(moveResult != null, "moveResult != null"); rval = new GoMoveResponse(GoResultCode.Success, move, moveResult); }); } catch (GoEngineException gex) { rval = new GoMoveResponse(gex.Code, null, null); } catch (Exception) { rval = new GoMoveResponse(GoResultCode.InternalError, null, null); } Debug.Assert(rval != null, "rval != null"); return(rval); }
public async Task <GoMoveResponse> GenMoveAsync(Guid id, GoColor color) { await LoadState(); GoMoveResponse rval = null; try { await Task.Run( async() => { await EnsureFuegoStartedAndMatchingGame(id); _state.Operation = GoOperation.GenMove; // This debug code generates a resign from the AI randomly. //int x = r.Next(5); //if (x == 0) //{ // newMove = new GoMove(MoveType.Resign, color, null); // //WriteCommand("play", color == GoColor.Black ? "black resign" : "white resign"); // //ReadResponse(); // result = AddMoveAndUpdateStateAndSaveToDatabase(newMove); // return; //} // Using kgs-genmove_cleanup for AI is important because // it will allow the final_status_list dead to be calculated // properly more often. // // This command captures the more obvious dead // stones before passing, though contrary to documentation // it does not capture ALL dead stones. // // Using just "genmove" will more often generate PASS prematurely // because it guesses too much about dead stones. Similarly, // "genmove" causes "final_status_list dead" to more often // generate strange results. var result = ParseResponse(WriteCommand("kgs-genmove_cleanup", color == GoColor.Black ? "black" : "white")); GoMove newMove; switch (result.Msg) { case "PASS": newMove = new GoMove(MoveType.Pass, color, null); break; case "resign": newMove = new GoMove(MoveType.Resign, color, null); break; default: newMove = new GoMove(MoveType.Normal, color, result.Msg); break; } // Add to move history and record new game state in database so user can // see what happened. var moveResult = AddMoveAndUpdateState(newMove); _state.Operation = GoOperation.Idle; await SaveState(); rval = new GoMoveResponse(GoResultCode.Success, newMove, moveResult); }); } catch (GoEngineException gex) { rval = new GoMoveResponse(gex.Code, null, null); } catch (Exception) { rval = new GoMoveResponse(GoResultCode.InternalError, null, null); } Debug.Assert(rval != null, "rval != null"); return(rval); }
public async Task <GoMoveResponse> GenMoveAsync(Guid gameid, GoColor color) { GoMoveResponse rval = null; try { await Task.Factory.StartNew( () => { EnsureFuegoStarted().Wait(); _state.Operation = GoOperation.GenMove; SaveState(); // This debug code generates a resign from the AI randomly. //int x = r.Next(5); //if (x == 0) //{ // newMove = new GoMove(MoveType.Resign, color, null); // //WriteCommand("play", color == GoColor.Black ? "black resign" : "white resign"); // //ReadResponse(); // result = AddMoveAndUpdateStateAndSaveToDatabase(newMove); // return; //} var result = ParseResponse(WriteCommand("genmove", color == GoColor.Black ? "black" : "white")); GoMove newMove; switch (result.Msg) { case "PASS": newMove = new GoMove(MoveType.Pass, color, null); break; case "resign": newMove = new GoMove(MoveType.Resign, color, null); break; default: newMove = new GoMove(MoveType.Normal, color, result.Msg); break; } // Add to move history and record new game state in database so user can // see what happened. var moveResult = AddMoveAndUpdateState(newMove); _state.Operation = GoOperation.Idle; SaveState(); rval = new GoMoveResponse(GoResultCode.Success, newMove, moveResult); }); } catch (GoEngineException gex) { rval = new GoMoveResponse(gex.Code, null, null); } catch (Exception ex) { rval = new GoMoveResponse(GoResultCode.ServerInternalError, null, null); } Debug.Assert(rval != null, "rval != null"); return(rval); }