/// <summary> /// 可能なら変化の自動再生を開始します。 /// </summary> /// <remarks> /// GUIスレッドで呼んでください。 /// </remarks> private void PlayVariation(VariationInfo variation, IEnumerable <BoardMove> bmoveList) { if (true) { return; } var shogi = Global.ShogiControl; if (shogi == null || shogi.AutoPlayState == AutoPlayState.Playing) { return; } // 引数にBoardを渡すことで、Boardそのものを変えながら // 自動再生を行うようにします。 var board = CurrentBoard.Clone(); var autoPlay = new AutoPlay(board, bmoveList) { IsChangeBackground = true, EndingInterval = TimeSpan.FromSeconds(0.1), }; autoPlay.Stopped += AutoPlay_Stopped; // 評価値を表示している変化に合わせます。 EvaluationValue = variation.Value; // 再生済みフラグを立ててしまいます。 variation.IsShowed = true; Board = board; shogi.StartAutoPlay(autoPlay); }
void AutoPlay_Stopped(object sender, EventArgs e) { Board = CurrentBoard.Clone(); EvaluationValue = CurrentEvaluationValue; this.lastPlayedTime = DateTime.Now; }
private void PerformMove(Move move) { LogMoveMove(CurrentMovingPlayer, move.FromFieldIndex, move.ToFieldIndex); CurrentBoard.GetField(move.FromFieldIndex).MoveTo(CurrentBoard.GetField(move.ToFieldIndex)); MovesMade++; TogglePawnDeletingOrSwitchPlayer(); }
public void RestartGame() { Score = 0; CurrentBoard.DeepClear(); _bricksQueue.Clear(); Play(); }
/// <summary> /// Converts the ChessState to a FEN board /// </summary> /// <returns>FEN board</returns> public string ToFenBoard() { StringBuilder strBuild = new StringBuilder(); strBuild.Append(CurrentBoard.ToPartialFenBoard()); if (CurrentPlayerColor == ChessColor.White) { strBuild.Append(" w"); } else { strBuild.Append(" b"); } //place holder for castling (not currently supported) strBuild.Append(" " + CastlingToFen()); //place holder for en passant (not currently supported) strBuild.Append(EnPassantToFen()); //half and full moves strBuild.Append(" " + HalfMoves.ToString() + " " + FullMoves.ToString()); return(strBuild.ToString()); }
private List <float> GetHardWeights(AIBoard board) { float p1spWeight = 1f; float p2spWeight = 1f; //Variables used in weight calculations. int playerOneSP = BoardAnalysis.FindShortestPath(board, true); int playerTwoSP = BoardAnalysis.FindShortestPath(board, true); int playerTwoNumWalls = CurrentBoard.GetPlayerTwoNumWalls(); int distanceBetweenPlayers = BoardAnalysis.FindDistanceBetween(CurrentBoard, CurrentBoard.GetPlayerOnePos(), CurrentBoard.GetPlayerTwoPos()); if (playerOneSP - playerTwoSP > 2) { p1spWeight = 5; } else if (playerOneSP < 5) { p1spWeight = 2; } List <float> w = new List <float> { p1spWeight, p2spWeight }; return(w); }
public void SquareClicked(IGridLocation clickedLocation) { ISquare clickedSquare = CurrentBoard[clickedLocation]; // If a piece is selected, try to move to the chosen location. if (SquareSelected) { Move attemptedMove = new Move(SelectedSquare.Location, clickedLocation); // If this is a possible move, execute the move. Then clear the selection either way. foreach (Move move in AvailableMoves.Where(move => move.Equals(attemptedMove))) { Execute(move); SendMoveMade(); return; } } if (clickedSquare.Type != PieceType.None && clickedSquare.Colour == PlayingColour) { SelectedSquare = clickedSquare; SquareSelected = true; SendHighlightsRequested(CurrentBoard.AvailableDestinations(SelectedSquare)); return; } }
private void GameLoop() { var stopwatch = new Stopwatch(); var millisecondsPassed = 0L; stopwatch.Start(); while (Alive) { if (stopwatch.ElapsedMilliseconds <= 100) { continue; } CurrentBoard.ShallowClear(); _inputHandler.HandlePlayerMovement(KeyboardHandler.GetDirection(), true); if (millisecondsPassed > 1000) { CurrentBoard.ShallowClear(); _inputHandler.HandlePlayerMovement(KeyCommand.Down); millisecondsPassed = 0L; } if (HasChanged) { Show(); } HasChanged = false; millisecondsPassed += stopwatch.ElapsedMilliseconds; stopwatch.Restart(); } }
public void PlayMove(Coordinate Location) { if (CurrentBoard.State == BoardState.InProgress) { CurrentBoard = CurrentBoard.Put(Location, CurrentPlayer); History.Add((CurrentPlayer, Location, CurrentBoard)); } }
//Does a game tree search 1 layer deep. public string GetEasyMove(string playerMove) { float weight1; if (MoveNum < 4) { weight1 = 0; } else if (MoveNum > 3 && MoveNum < 8) { weight1 = 2; } else { weight1 = new System.Random().Next(0, 1); } TreeNode.weights = new List <float> { weight1, 1f }; TreeNode.wallValues = new List <float> { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f }; HandlePlayerMove(playerMove); TreeNode rootNode = new TreeNode(CurrentBoard); Dictionary <string, float> depthOneValues = IterateStart(rootNode, 1); Dictionary <string, float> depthTwoValues = IterateStart(rootNode, 2); string moveSelected = "error"; float max = float.NegativeInfinity; foreach (KeyValuePair <string, float> move in depthOneValues) { float moveValue; if (depthTwoValues[move.Key] > 1000 || depthTwoValues[move.Key] < -1000) { moveValue = depthTwoValues[move.Key]; } else { moveValue = move.Value; } if (max < moveValue) { max = moveValue; moveSelected = move.Key; } } CurrentBoard.MakeMove(moveSelected); MoveNum++; return(moveSelected); }
public void NextBrick() { CurrentBrick = _bricksQueue.Dequeue(); EnqueueNewBrick(); CurrentBrick.RestartPosition(_random.Next(CurrentBoard.Width - CurrentBrick.Width)); if (CurrentBoard.IsColliding(CurrentBrick, 0, 0)) { Alive = false; } }
private void HandlePawnPlacing(int fieldIndex) { Field selectedField = CurrentBoard.GetField(fieldIndex); if (selectedField.Empty) { CurrentPlayerPlacePawn(fieldIndex); TogglePawnDeletingOrSwitchPlayer(); } }
public IList <SearchTTEntry> SearchMove(SearchParams searchParams) { if (CurrentBoard == null) { SetStartingPos(); } var searchResult = Search.Search(CurrentBoard, searchParams); CurrentBoard = CurrentBoard.DoMove(searchResult[0].Move); return(searchResult); }
public void HandlePawnRemoval(int fieldIndex) { Field field = CurrentBoard.GetField(fieldIndex); if (!field.Empty) { if (!field.BelongsTo(CurrentMovingPlayer)) { RemovePawn(field); } } }
public void SetPositionByMoves(bool startNewBoard, IEnumerable <string> moves) { if (startNewBoard) { SetStartingPos(); } foreach (var moveStr in moves) { var move = Move.FromPositionString(CurrentBoard, moveStr); CurrentBoard = CurrentBoard.DoMove(move); } }
static Board Simulate(Action move) { var board = CurrentBoard.Copy(); var playerId = 0; // Start Simulating var unit = board.Units[playerId, move.Index]; // MOVE&BUILD : if (move.Type == "MOVE&BUILD") { // MOVE int oldHeight = board.Cases[unit.X, unit.Y].Height; unit.X = unit.X + Board.Offsets[move.Dir1, 0]; unit.Y = unit.Y + Board.Offsets[move.Dir1, 1]; // Scores data move.HeightDifference = board.Cases[unit.X, unit.Y].Height - oldHeight; move.PointScored = board.Cases[unit.X, unit.Y].Height == 3; // BUILD var buildX = unit.X + Board.Offsets[move.Dir2, 0]; var buildY = unit.Y + Board.Offsets[move.Dir2, 1]; //TODO : check if occupied by a potential ennemy position board.Cases[buildX, buildY].Height++; } else if (move.Type == "PUSH&BUILD") { // PUSH var newX = unit.X + Board.Offsets[move.Dir1, 0]; var newY = unit.Y + Board.Offsets[move.Dir1, 1]; int oldEnnemyHeight = board.Cases[newX, newY].Height; for (int u = 0; u < Board.UnitsPerPlayer; ++u) { Unit ennemyUnit = board.Units[1 - playerId, u]; if (ennemyUnit.X == newX && ennemyUnit.Y == newY) { ennemyUnit.X = ennemyUnit.X + Board.Offsets[move.Dir2, 0]; ennemyUnit.Y = ennemyUnit.Y + Board.Offsets[move.Dir2, 1]; move.EnnemyPushedHeightDifference = board.Cases[ennemyUnit.X, ennemyUnit.Y].Height - oldEnnemyHeight; break; } } // BUILD board.Cases[newX, newY].Height++; } return(board); }
/// <summary> /// 現局面の指し手を進めます。 /// </summary> public void DoMove(BoardMove bmove, int seconds) { var prevCurrentBoard = CurrentBoard.Clone(); // 符号は設定されていないことがあります。 //csaMove.Side = CurrentBoard.Turn; /*var bmove = CurrentBoard.ConvertCsaMove(csaMove); * if (bmove == null || !bmove.Validate()) * { * Log.Error("{0}手目 {1}を変換できませんでした。", * CurrentBoard.MoveCount, * csaMove.ToPersonalString()); * return; * }*/ if (!CurrentBoard.DoMove(bmove)) { Log.Error("{0}手目 {1}を指せませんでした。", CurrentBoard.MoveCount, bmove); return; } // 手番側の残り時間を減らしたのち、手番を入れ替えます。 DecBaseLeaveTime(CurrentTurn, seconds); InitBoard(CurrentBoard, false, false); WPFUtil.UIProcess(() => { // 実際に指した手と一致する変化は残します。 var list = VariationList .Where(_ => _.MoveList.Count() >= 2) .Where(_ => bmove.Equals(_.MoveList[0])) .Select(_ => new VariationInfo { IsShowed = false, MoveList = _.MoveList.Skip(1).ToList(), Value = _.Value, NodeCount = _.NodeCount, }) .ToList(); VariationList.Clear(); list.ForEach(_ => VariationList.Add(_)); // 指し手の再生を行います。 AddDoMoveAutoPlay(prevCurrentBoard, bmove); }); }
public void GenerateMoves() { if (!_leaf) { if (CurrentBoard.Checkmated(PlayingColour)) { SendGameOver(NonPlayingColour()); } else if (CurrentBoard.Stalemate(PlayingColour)) { SendGameOver(PieceColour.None); } } }
public EStatus MoveTile(Position kTilePosition, out MoveDirection kBlankTileMoveDirection) { Position kBlankTilePosition = CurrentBoard.BlankTilePosition; kBlankTileMoveDirection = GetBlankTileMoveDirection(kBlankTilePosition, kTilePosition); if (kBlankTileMoveDirection.Equals(MoveDirection.None)) { return(EStatus.FAILURE); } CurrentBoard = CurrentBoard.Move(kBlankTileMoveDirection); BoardInputText = BoardToText(CurrentBoard); return(EStatus.SUCCESS); }
public void MakeMove(ChessMove move) { PreviousMove = move; PreviousBoard = CurrentBoard.Clone(); CurrentBoard.MakeMove(move); if (CurrentPlayerColor == ChessColor.White) { CurrentPlayerColor = ChessColor.Black; } else { CurrentPlayerColor = ChessColor.White; } }
//This handles game start logic and updating the board during the game. private void HandlePlayerMove(string playerMove) { //AI starts on e9 and makes the first move of the game. if (playerMove == "gamestart") { CurrentBoard.PlayerTwoGoesFirst(); } //AI starts on e1 and makes the first move of the game. else if (playerMove == "") { } //Updates the board with the player's move. else { CurrentBoard.MakeMove(playerMove); } }
void RemoveElement(Hex hex) { var position = CurrentBoard?.GetPosition(hex); if (position == null) { return; } if (!position.HasData()) { return; } var data = position.Data; position.RemoveData(); OnRemoveElement(data, GetCellCoordinate(hex)); }
private void OnNodeSwipeOccurred(NodeButtonBehavior down, NodeButtonBehavior up, Vector2 dir) { var fromNode = CurrentBoard.GetOffsetNode(down.XIndex, down.YIndex); var toNode = CurrentBoard.GetOffsetNode(up.XIndex, up.YIndex); if (fromNode == null || toNode == null) { return; } var dist = Vector2.Distance(fromNode.Behavior.transform.position, toNode.Behavior.transform.position); if (!(dist <= 1.25f)) { return; } fromNode.SendEnergy(toNode); EnergyTransferCount++; }
void AddElement(BoardElement element, Hex hex) { var position = CurrentBoard.GetPosition(hex); if (position == null) { return; } if (position.HasData()) { return; } position.AddData(element); var cell = GetCellCoordinate(hex); OnAddElement(element, cell); }
private IEnumerable <BoardMove> GetVariationMoveList(VariationInfo variation) { var board = CurrentBoard.Clone(); var bmoveList = new List <BoardMove>(); foreach (var bmove in variation.MoveList) { if (!board.DoMove(bmove)) { break; } bmoveList.Add(bmove); } // 7手以下の場合は、再生しません。 return(bmoveList.Count < 7 ? null : bmoveList); }
private async void Solve() { OnCreateBoard(new CreateBoardEventArgs(CurrentBoard)); if (!CurrentBoard.IsSolvable()) { if (!_dialogService.ShowConfirmation("Looks like this board is not solvable. Are you sure you want to continue?")) { return; } } CreateCancellationToken(); SearchResult = null; State = EWorkState.SEARCHING; try { SearchResult = await _puzzleSolverService.SolveAsync(CurrentBoard, SelectedAlgorithm, SelectedHeuristicFunction, _cancellationToken); if (!SearchResult.Success) { _dialogService.ShowError("Solution was not found."); } else { StartShowingMoves(); return; } } catch (OperationCanceledException) { } catch (Exception ex) { _dialogService.ShowError(ex.Message); } State = EWorkState.IDLE; }
private void HandlePawnMoving(int fieldIndex) { Field newField = CurrentBoard.GetField(fieldIndex); PlayerNumber selectedFieldPawnPlayer = newField.PawnPlayerNumber; if (selectedFieldPawnPlayer == CurrentMovingPlayer) { LastSelectedField = newField; } else if (LastSelectedField != null && newField.Empty) { if (CurrentPlayersPawnsLeft <= FLYING_PAWNS_NUMBER) { HandleFlyingMove(newField); } else { HandleNormalMove(newField); } } }
public MainWindow() { InitializeComponent(); MAX_SQUARE = Gomuku.Properties.Settings.Default.MAX_SQUARE; BoardChess = new CurrentBoard(); LButton = new Button[MAX_SQUARE, MAX_SQUARE]; myMessage = new ObservableCollection <Message>(); DrawBoardChess(); rdbPlayerVsPlayer.IsChecked = true; myMessage.Add(new Message("Server", "Hello! Welcome to Gomoku!")); ChatBox.ItemsSource = myMessage; #region Khai báo Delegate BoardChess.BoardChessOffline.PlayerWin += PlayerWinEvent; BoardChess.BoardChessOffline.PlayerDicken += PlayerDickenEvent; BoardChess.BoardChessOffline.PaintCellEvent += PaintCellBoardChessOffline; BoardChess.BoardChessOffline.HighlightCellWinnerEvent += HighlightCellWinnerEvent; BoardChess.Socket.PaintCellEvent += PaintCellBoardChessOnline; BoardChess.Socket.ShowMessageEvent += ShowMessageEvent; BoardChess.Socket.EndGameEvent += EndGameOnlineEvent; BoardChess.Socket.HighlightCellWinnerEvent += HighlightCellWinnerEvent; #endregion }
private List <GameState> GetFirstStageNextPossibleStates(PlayerNumber playerNumber) { PlayerNumber otherPlayerNumber = playerNumber == PlayerNumber.FirstPlayer ? PlayerNumber.SecondPlayer : PlayerNumber.FirstPlayer; List <GameState> gameStates = new List <GameState>(); List <Field> emptyFields = CurrentBoard.GetEmptyFields(); foreach (var emptyField in emptyFields) { GameState nextGameState = PawnPlacingGameStateFromThis(playerNumber, emptyField.FieldIndex); HashSet <Mill> millDifference = nextGameState.MillDifference(this); if (millDifference.Count == 0) { gameStates.Add(nextGameState); } else if (millDifference.Count == 1) { List <Field> otherPlayersFields = nextGameState.CurrentBoard.GetPlayerFields(otherPlayerNumber); foreach (var otherPlayerField in otherPlayersFields) { gameStates.Add(nextGameState.PawnRemovalGameStateFromThis(otherPlayerField.FieldIndex)); } } else { List <Field> otherPlayersFields = nextGameState.CurrentBoard.GetPlayerFields(otherPlayerNumber); for (int i = 0; i < otherPlayersFields.Count - 1; i++) { GameState firstRemovedPawnGameState = nextGameState.PawnRemovalGameStateFromThis(otherPlayersFields[i].FieldIndex); for (int j = i + 1; j < otherPlayersFields.Count; j++) { GameState secondRemovedPawnGameState = firstRemovedPawnGameState.PawnRemovalGameStateFromThis(otherPlayersFields[j].FieldIndex); } } } } return(gameStates); }
//Initiates a minimax search 2 layers deep. public string GetHardMove(string playerMove) { timer.Start(); TreeNode.weights = GetHardWeights(CurrentBoard); TreeNode.wallValues = new List <float> { 2f, 2f, 2f, 2f, 1f, 1f, 1f, 1f, 1f, 0f }; //AI starts on e9 and makes the first move of the game. if (playerMove == "gamestart") { CurrentBoard.PlayerTwoGoesFirst(); } //AI starts on e1 and makes the first move of the game. else if (playerMove == "") { } //Updates the board with the player's move. else { CurrentBoard.MakeMove(playerMove); } TreeNode rootNode = new TreeNode(CurrentBoard); float rootNodeValue = rootNode.CalcValue(); List <TreeNode> possibleMoves = rootNode.GetChildren(); //Create dictionary of all useful values of first two levels of analysis. Dictionary <string, MoveInfo> moveValues = new Dictionary <string, MoveInfo>(); foreach (TreeNode moveNode in possibleMoves) { if (timer.ElapsedMilliseconds > 5980) { break; } MoveInfo thisMovesInfo = new MoveInfo(); foreach (TreeNode childNode in moveNode.GetChildren()) { thisMovesInfo.UpdateValues(childNode.CalcValue(), moveNode.CalcValue()); } moveValues.Add(moveNode.GetMoveMade(), thisMovesInfo); } string selectedMove = "none1"; //Minimax of the first two levels. List <string> movesSelected = new List <string>(); float value = float.NegativeInfinity; foreach (KeyValuePair <string, MoveInfo> pair in moveValues) { if (pair.Value.singleLevelValue > 10000) { value = pair.Value.singleLevelValue; movesSelected.Clear(); movesSelected.Add(pair.Key); break; } if (pair.Value.min > value) { value = pair.Value.min; movesSelected.Clear(); movesSelected.Add(pair.Key); } else if (pair.Value.min == value) { movesSelected.Add(pair.Key); } } selectedMove = movesSelected[new System.Random().Next(0, movesSelected.Count)]; //If selected move isn't a wall then use the pawn moves single level evaluation. //And if jump next move isn't a possibility. bool isPawnMove = !(selectedMove.EndsWith("h") || selectedMove.EndsWith("v")); bool jumpPossible = BoardAnalysis.FindDistanceBetween(CurrentBoard, CurrentBoard.GetPlayerOnePos(), CurrentBoard.GetPlayerTwoPos()) == 2; if (isPawnMove && !jumpPossible) { List <string> pawnMoves = CurrentBoard.GetPawnMoves(); value = float.NegativeInfinity; selectedMove = "none2"; foreach (string pm in pawnMoves) { float tempVal = moveValues[pm].singleLevelValue; if (tempVal > value) { selectedMove = pm; value = tempVal; } } } float testVal = value - rootNodeValue; if (value - rootNodeValue < 3) { float currentPotential = float.NegativeInfinity; float currentRisk = float.NegativeInfinity; movesSelected.Clear(); foreach (KeyValuePair <string, MoveInfo> pair in moveValues) { if (pair.Key.EndsWith("h") || pair.Key.EndsWith("v")) { float optimisticPotential = pair.Value.max - rootNodeValue; float pessemisticPotential = pair.Value.min - rootNodeValue; float risk = optimisticPotential - pessemisticPotential; if (optimisticPotential > 2) { if (optimisticPotential > currentPotential) { movesSelected.Clear(); movesSelected.Add(pair.Key); currentPotential = optimisticPotential; currentRisk = risk; } else if (optimisticPotential == currentPotential) { if (risk < currentRisk) { movesSelected.Clear(); movesSelected.Add(pair.Key); currentPotential = optimisticPotential; currentRisk = risk; } else if (risk == currentRisk) { movesSelected.Add(pair.Key); } } } } } if (movesSelected.Count > 0) { selectedMove = movesSelected[new System.Random().Next(0, movesSelected.Count)]; } } timer.Reset(); CurrentBoard.MakeMove(selectedMove); return(selectedMove); }