public void GameHistoryTest() { GameHistory gameHistory = new GameHistory(); Game game = new Game(new StartMenu()); game.GenerateNewGame(); var robotEnegry = game.Robot.BatteryCharge; game.State = new GameProcess(); Assert.AreEqual(game.Robot.BatteryCharge, robotEnegry); gameHistory.Add(new GameMemento(game.Robot.SaveState(), game.MoveCounter, (Map)game.Map.Clone())); var res = game.Turn("next"); Assert.AreEqual(res, "In fronr of you lies: " + game.Map.Stones[1].GetInfo() + "\r\nWhat will U do?\r\n\r\n" + (game.Robot is Cyborg ? "Turns harm: 0, battery charge: " : "Battery charge: ") + +(robotEnegry - 1) + ", battery lost: " + 1 + ", "); Assert.AreEqual(game.Robot.BatteryCharge, robotEnegry - 1); game.Robot.RestoreState(gameHistory.GetLastState().GetRobotMemento()); Assert.AreEqual(game.Robot.BatteryCharge, robotEnegry); }
/// <summary> /// Startet - abhängig davon, ob die KI zufällig oder lernend ist- die Funktion MakeTurn des Objektes AI. /// Im Anschluss werden die Funktionen für das Spielende, Spielerwechsel und die Aktualisierung der View aufgerufen. /// /// Speichert die Ausgangslage (GameHistory) und die erfolgte Entscheidung(DecisionHistory) in den entsprechenden Variablen. /// </summary> /// <param name="learning_AI"> Ist die KI eine lernende KI?</param> private void MakeTurn_AI(Boolean learning_AI) { //aktuelle Spielsituation wird gespeichert GameHistory.Add(GameState.Board.Clone() as int[]); if (!learning_AI) { GameState.Board = AI.Random_MakeTurn(GameState.Board, GameState.ActivePlayer); } else if (learning_AI) { GameState.Board = AI.Learning_MakeTurn(GameState.Board, GameState.ActivePlayer); } //Entscheidung der KI wird gespeichert, nachdem der letzte Zug der KI ermittelt wurde. for (int i = 0; i < 9; i++) { if (GameState.Board[i] != GameHistory.Last()[i] && GameState.Board[i] == GameState.ActivePlayer) { DecisionHistory.Add(i); } } TestForEndCondition(); PlayerChange(); SendInformationToVM(); }
public bool MakeMove(TicTacToeMove move) { var(player, i, j) = move; if (!CheckBounds(i, j)) { return(false); } if (player.Mark == CurrentMove && Board[i, j] == TicTacToeMarkEnum.NaN) { Board[i, j] = player.Mark; CurrentMove = CurrentMove == TicTacToeMarkEnum.O ? TicTacToeMarkEnum.X : TicTacToeMarkEnum.O; } else { return(false); } // move is done GameHistory.Add(move); if (GameEnd()) { OnGameEnd?.Invoke(); } return(true); }
private void GetGameUpdates(UdpClient client) { Log("Receiving GameSteps"); try { while (!_shutdown) { IPEndPoint endPoint = null; var msg = client.Receive(ref endPoint); using (var br = new BinaryReader(new MemoryStream(msg))) { if ((SC_Message)msg[0] == SC_Message.GameStepCollection) { GameStepCollection gsc = new GameStepCollection(br); foreach (var gs in gsc.GameSteps) { if (gs.StepNumber > _highestGameStepNum + 8) { Log("Disconnected!"); throw new Exception("Disconnected!"); } _highestGameStepNum = Math.Max(gs.StepNumber, _highestGameStepNum); lock (_gameHistory) { _gameHistory.Add(gs); } if (gs.PlayerInputs.Any()) { var msgs = gs.PlayerInputs .Select(pi => pi.Key + ":" + String.Join("|", pi.Value.Inputs.Select(k => k.Key + ":" + k.Value).ToArray())) .Aggregate((a, e) => a + "," + e); //Log("[" + gs.StepNumber + "] " + msgs); } } } else { Log("Invalid Message!"); } } } } catch (Exception e) { Log(e.ToString()); } Log("GetGameSteps Exit"); }
public void Notify(string eventDetail) { if (GameHistory is null) { GameHistory = new List <GameEvent>(); } GameHistory.Add(new GameEvent { EventDetail = eventDetail }); }
/// <summary> /// Testet, ob das angegebene Feld frei war. Sollte es nicht frei gewesen sein, so passiert nichts. /// Ist es ein Freies Feld, so wird es mit der Nummer des Spieler überschrieben, /// /// /// Die AusgabeVariable gibt dem ViewModel die Informationen, ob der Zug gültig war und welcher Spieler diesen durchgeführt hat. /// Ausgabe = 0 : Zug ungültig /// 1 : Spieler "X" hat gezogen /// 5 : Spieler "X" hat gewonnen /// -1 : Spieler "O" hat gezogen /// -5 : Spieler "O" hat gewonnen /// 100 : Spiel mit Unendschieden beendet /// /// Speichert die Ausgangslage (GameHistory) und die erfolgte Entscheidung(DecisionHistory) in den entsprechenden Variablen. /// </summary> /// <param name="point"></param> /// <returns></returns> public void MakeTurn(int point) { if (GameState.Board[point] == 0) { GameHistory.Add(GameState.Board.Clone() as int[]); GameState.Board[point] = GameState.ActivePlayer; DecisionHistory.Add(point); TestForEndCondition(); PlayerChange(); ChooseAI(); SendInformationToVM(); } }
/// <summary> /// IParson行動通知イベントハンドラ /// </summary> /// <param name="parson">通知元</param> /// <param name="action">行動</param> private void OutputParsonAction(IParson parson, string action) { if (Application.Current == null || Application.Current.Dispatcher == null) { return; } Application.Current.Dispatcher.Invoke(() => { GameHistory.Add(new GameHistoryItem() { Parson = parson, Action = action }); }, System.Windows.Threading.DispatcherPriority.Background); }
public Anwsers Anwser(int proposal) { if (randomized > proposal) { GameHistory.Add(new Move(proposal, Anwsers.TooLittle)); return(Anwsers.TooLittle); } else if (randomized < proposal) { GameHistory.Add(new Move(proposal, Anwsers.TooMuch)); return(Anwsers.TooMuch); } else { Status = GameStatus.Finished; return(Anwsers.Score); } } //publiczna metoda typu Anwsers (ten typ to enum)
public sealed override void ReceiveMove(IMove opponentMove) { LatestOpponentMove = opponentMove; if (!_connectionTestOverride) { // Basic validation var move = new SingleMove(opponentMove); if (Board.ValueAt(move.PrevPos) == null) { throw new ArgumentException($"Player [isWhite={!IsPlayerWhite}] Tried to move a from position that is empty"); } if (Board.ValueAt(move.PrevPos) is PieceBase opponentPiece) { if (opponentPiece.IsWhite == IsPlayerWhite) { throw new ArgumentException($"Opponent tried to move player piece"); } } // TODO intelligent analyzing what actually happened if (Board.ValueAt(move.NewPos) is PieceBase playerPiece) { // Opponent captures player targetpiece if (playerPiece.IsWhite == IsPlayerWhite) { move.Capture = true; } else { throw new ArgumentException("Opponent tried to capture own piece."); } } Board.ExecuteMove(move); GameHistory.Add(opponentMove); TurnCount++; } }
public async Task PlayNextGameAsync() { var nextCompetitors = Elimination.GetNextCompetitors(); GameOverTextVisibility = Visibility.Collapsed; if (nextCompetitors != null) { var gameHistoryEntry = new GameHistoryEntryViewModel() { GameDescription = Elimination.GetGameDescription(), History = new ObservableCollection <RoundPartialHistory>() }; Game.SetupNewGame(nextCompetitors); GameHistory.Add(gameHistoryEntry); OutputText += "Game starting: " + gameHistoryEntry.GameDescription + "\n"; await PlayGameAsync(gameHistoryEntry); } }
public async Task PlayNextGameAsync() { var nextCompetitors = Elimination.GetNextCompetitors(); if (nextCompetitors != null) { await SetArenaMessage(ArenaMessageHelper.GetInitialMessage(nextCompetitors)); var gameHistoryEntry = new GameHistoryEntryViewModel() { GameDescription = Elimination.GetGameDescription(), History = new ObservableCollection <RoundPartialHistory>() }; Game.SetupNewGame(nextCompetitors); GameHistory.Add(gameHistoryEntry); OutputText += "Game starting: " + gameHistoryEntry.GameDescription + "\n"; await PlayGameAsync(gameHistoryEntry); } }
public async Task <GameState> LoadHistoryGetState() { var tokens = accountHandler.FindTokenByMetadata(Player1Address, "GameId", Id.ToString()); GameState lastState = null; GameHistory.Clear(); GameHistoryTxIds.Clear(); //var tok = tokens.Values.OrderBy(t => t.TimeStamp); foreach (var t in tokens) { try { if (t.Value.Metadata != null) { if (t.Value.Metadata.TryGetValue("GameData", out var gameData)) { var parsedData = JsonConvert.DeserializeObject <ChessGameDto>(gameData); if (parsedData != null) { if (parsedData.GameId == Id.ToString() && parsedData.Type == GameDtoTypes.ChessGame) { //GameHistoryTxIds.Add(t.Key); if (parsedData.Players.Count > 0) { Players = parsedData.Players; } parsedData.TxId = t.Key; parsedData.TimeStamp = t.Value.TimeStamp; GameHistory.Add(parsedData); } lastState = JsonConvert.DeserializeObject <GameState>(parsedData.GameState); } } } } catch (Exception ex) { log.Error("Chess Game - wrong format of gameData in token metadata. Cannot load history", ex); return(null); } } var ghist = GameHistory.OrderBy(t => t.TimeStamp); GameHistory = ghist.ToList <ChessGameDto>(); foreach (var gh in GameHistory) { GameHistoryTxIds.Add(gh.TxId); } var last = GameHistoryTxIds.LastOrDefault(); if (last != null) { ActualStateTxId = last; } return(await Task.FromResult(lastState)); }
public async Task <string> WriteMove(string stateString, string onMoveAddress, string player2Address, string password = "") { GameState state = null; if (!string.IsNullOrEmpty(stateString)) { state = GetGameStateFromString(stateString); } else { return(await Task.FromResult("Cannot load state String. It is empty!")); } if (!Players.ContainsKey(onMoveAddress) || !Players.ContainsKey(player2Address)) { return(await Task.FromResult("Player address is not in the list of players!")); } try { state.LastMovePlayer = onMoveAddress; var dto = new ChessGameDto() { GameId = Id.ToString(), GameState = JsonConvert.SerializeObject(state), Type = GameDtoTypes.ChessGame, LastGameRecordTxId = ActualStateTxId }; dto.Players = new Dictionary <string, ChessPlayer>(); foreach (var pl in Players) { dto.Players.TryAdd(pl.Key, pl.Value); } GameHistory.Add(dto); var moveString = JsonConvert.SerializeObject(dto); var tkData = new SendTokenTxData() { Amount = 1, Symbol = TokenSymbol, ReceiverAddress = player2Address, SenderAddress = onMoveAddress, Id = TokenId }; tkData.Metadata.TryAdd("GameId", Id.ToString()); tkData.Metadata.TryAdd("GameData", moveString); tkData.Password = password; var res = await NeblioTransactionHelpers.SendNTP1TokenAPI(tkData, 30000); if (!string.IsNullOrEmpty(res)) { ActualStateTxId = res; } return(await Task.FromResult(res)); } catch (Exception ex) { log.Error("Chess Game - Cannot write move!", ex); return(await Task.FromResult("ERROR")); } }
public async Task <string> LoadHistoryFromActualTx() { try { var allLoaded = false; var actualTxLoading = ActualStateTxId; while (!allLoaded) { var info = await NeblioTransactionHelpers.TransactionInfoAsync(null, TransactionTypes.Neblio, actualTxLoading); if (info == null) { return(await Task.FromResult("OK - No History yet.")); } if (info.VoutTokens != null) { if (info.VoutTokens.Count > 0) { var token = info.VoutTokens[0]; if (token.Metadata != null) { if (token.Metadata.Count > 0) { if (token.Metadata.TryGetValue("GameId", out var gameid)) { if (gameid == Id.ToString()) { if (token.Metadata.TryGetValue("GameData", out var gameData)) { if (!string.IsNullOrEmpty(gameData)) { try { var parsedData = JsonConvert.DeserializeObject <ChessGameDto>(gameData); if (parsedData != null) { if (parsedData.GameId == Id.ToString() && parsedData.Type == GameDtoTypes.ChessGame) { GameHistoryTxIds.Add(actualTxLoading); if (Players.Count == 0 && parsedData.Players.Count > 0) { Players = parsedData.Players; } GameHistory.Add(parsedData); if (parsedData.LastGameRecordTxId != "StartOfNewGame") { actualTxLoading = parsedData.LastGameRecordTxId; } else { allLoaded = true; } } } } catch (Exception ex) { log.Error("Chess Game - wrong format of gameData in token metadata. Cannot load history", ex); return(null); } } } } } } } } } } // loading is going from newset to oldest one, so it is important to reverse whole list GameHistoryTxIds.Reverse(); GameHistory.Reverse(); return(await Task.FromResult("OK")); } catch (Exception ex) { log.Error("Chess Game - Cannot load game History!", ex); return(await Task.FromResult("ERROR")); } }
private IPlayerMove CreateNewMove(bool checkOpenings, int?overrideSearchDepth = null) { var isMaximizing = IsPlayerWhite; Diagnostics.StartMoveCalculations(); // Common start measures if (Settings.UseTranspositionTables) { // Delete old entries from tables var transpositions = Board.Shared.Transpositions.Tables; if (transpositions.Any()) { var toBeDeleted = new List <ulong>(); var currentTurnCount = Board.Shared.GameTurnCount; foreach (var transposition in transpositions) { // If transposition.turn 20 < current 25 - 4 if (transposition.Value.GameTurnCount < currentTurnCount - Settings.ClearSavedTranspositionsAfterTurnsPassed) { toBeDeleted.Add(transposition.Key); } } foreach (var hash in toBeDeleted) { transpositions.Remove(hash); } if (Settings.UseFullDiagnostics) { if (toBeDeleted.Any()) { Diagnostics.AddMessage($"Deleted {toBeDeleted.Count} old transposition entries."); } Diagnostics.AddMessage($"Total transpositions: {transpositions.Count}."); } } } // Opening if (GameHistory.Count < 10 && checkOpenings) { var previousMoves = GetPreviousMoves(); var openingMove = Openings.NextMove(previousMoves); if (openingMove != null) { var openingMoveWithData = Board.CollectMoveProperties(openingMove); Board.ExecuteMove(openingMoveWithData); Board.Shared.GameTurnCount++; PreviousData = Diagnostics.CollectAndClear(); var result = new PlayerMoveImplementation( openingMove.ToInterfaceMove(), PreviousData.ToString()); GameHistory.Add(result.Move); return(result); } } // Get all available moves and do necessary filtering List <SingleMove> allMoves = Board.Moves(isMaximizing, true, true).ToList(); if (allMoves.Count == 0) { // Game ended to stalemate throw new ArgumentException( $"No possible moves for player [isWhite={IsPlayerWhite}]. Game should have ended to draw (stalemate)."); } if (MoveHistory.IsLeaningToDraw(GameHistory)) { // Take 4th from the end of list var repetionMove = GameHistory[^ 4];
private void SendPlayerUpdates() { Console.WriteLine("Starting Broadcasts"); _lastStepBroadcast = DateTime.UtcNow; DateTime start = DateTime.UtcNow; int sleepIntervalMs = GameStepIntervalMs; try { while (true) { if (sleepIntervalMs > 0) { Thread.Sleep(sleepIntervalMs); } start = DateTime.UtcNow; GameStep gameStep; lock (_gameLock) { byte ellapsed = (byte)Math.Min((DateTime.UtcNow - _lastStepBroadcast).TotalMilliseconds, byte.MaxValue); // Create new GameStep to broadcast gameStep = new GameStep(_stepNumber, ellapsed); GameStep lastGameStep; // If previous GameSteps exit if (_gameHistory.Count > 0 && _gameHistory.TryGet((UInt16)(_stepNumber - 1), out lastGameStep)) { foreach (var currentInput in _curPlayerInputs) { // If Player input exists from last game update, take XOR of last player input and current player input PlayerInputs lastInput; if (lastGameStep.PlayerInputs.TryGetValue(currentInput.Key, out lastInput)) { var changed = currentInput.Value.Inputs .Where(i => !lastInput.Inputs.ContainsKey(i.Key) || lastInput.Inputs[i.Key] != i.Value) .ToDictionary(k => k.Key, k => k.Value); PlayerInputs pi = new PlayerInputs() { PlayerId = currentInput.Key, Inputs = changed }; gameStep.PlayerInputs.Add(pi.PlayerId, pi); } // If no last game update for this player, just send current inputs else { gameStep.PlayerInputs.Add(currentInput.Key, currentInput.Value); } } _curPlayerInputs.Clear(); } // If no previous GameSteps exist else { gameStep.PlayerInputs = _curPlayerInputs; } _gameHistory.Add(gameStep); } GameStepCollection gsc = new GameStepCollection(3); gsc.GameSteps.Add(gameStep); // Send Redundant Step #1 if (_stepNumber >= 1) { UInt16 idx = (UInt16)Math.Max(_stepNumber - 2, 0); GameStep redundant; if (_gameHistory.TryGet(idx, out redundant)) { gsc.GameSteps.Add(redundant); } } // Send Redundant Step #2 if (_stepNumber >= 3) { UInt16 idx = (UInt16)Math.Max(_stepNumber - 8, 0); GameStep redundant; if (_gameHistory.TryGet(idx, out redundant)) { gsc.GameSteps.Add(redundant); } } BroadcastGameStepCollection(gsc); // Calculate next Sleep Interval _lastStepBroadcast = DateTime.UtcNow; _stepNumber++; TimeSpan broadcastDuration = (_lastStepBroadcast - start); sleepIntervalMs = Math.Max(GameStepIntervalMs - (int)broadcastDuration.TotalMilliseconds, 0); } } catch (Exception e) { Console.Write(e); } }
void OnGameUpdate(Stone.StoneState state) => gameHistory.Add(game.Board, state);
public override IPlayerMove CreateMove() { if (_connectionTestOverride) { var diagnostics = Diagnostics.CollectAndClear(); // Dummy moves for connection testing var move = new PlayerMoveImplementation() { Move = new MoveImplementation() { StartPosition = $"a{_connectionTestIndex--}", EndPosition = $"a{_connectionTestIndex}", PromotionResult = PromotionPieceType.NoPromotion }, Diagnostics = diagnostics.ToString() }; return(move); } else { var isMaximizing = IsPlayerWhite; Diagnostics.StartMoveCalculations(); // Get all available moves and do necessary filtering List <SingleMove> allMoves = Board.Moves(isMaximizing, true, true).ToList(); if (allMoves.Count == 0) { throw new ArgumentException($"No possible moves for player [isWhite={IsPlayerWhite}]. Game should have ended to draw (stalemate)."); } // Reorder moves to improve alpha-beta cutoffs // allMoves = MoveResearch.OrderMoves(allMoves, Board, isMaximizing); if (MoveHistory.IsLeaningToDraw(GameHistory)) { var repetionMove = GameHistory[GameHistory.Count - 4]; allMoves.RemoveAll(m => m.PrevPos.ToAlgebraic() == repetionMove.StartPosition && m.NewPos.ToAlgebraic() == repetionMove.EndPosition); } Diagnostics.AddMessage($"Available moves found: {allMoves.Count}. "); Strategy.Update(PreviousData, TurnCount); var strategyResult = Strategy.DecideSearchDepth(PreviousData, allMoves, Board); SearchDepth = strategyResult.searchDepth; Phase = strategyResult.gamePhase; var bestMove = AnalyzeBestMove(allMoves); if (bestMove == null) { throw new ArgumentException($"Board didn't contain any possible move for player [isWhite={IsPlayerWhite}]."); } // Update local Board.ExecuteMove(bestMove); TurnCount++; // Endgame checks // TODO should be now read from singlemove var castling = false; var check = Board.IsCheck(IsPlayerWhite); //var checkMate = false; //if(check) checkMate = Board.IsCheckMate(IsPlayerWhite, true); if (bestMove.Promotion) { Diagnostics.AddMessage($"Promotion occured at {bestMove.NewPos.ToAlgebraic()}. "); } PreviousData = Diagnostics.CollectAndClear(); var move = new PlayerMoveImplementation() { Move = bestMove.ToInterfaceMove(castling, check), Diagnostics = PreviousData.ToString() }; GameHistory.Add(move.Move); return(move); } }