// Empty corner: The player plays in a corner square. private IList <int> FindEmptyCorners() { IList <int> indicies = new List <int>(); Tic corner1 = _board.Get(1); if (corner1 == Tic.None) { indicies.Add(1); } Tic corner3 = _board.Get(3); if (corner3 == Tic.None) { indicies.Add(3); } Tic corner7 = _board.Get(7); if (corner7 == Tic.None) { indicies.Add(7); } Tic corner9 = _board.Get(9); if (corner9 == Tic.None) { indicies.Add(9); } return(indicies); }
// Empty side: The player plays in a middle square on any of the 4 sides. private IList <int> FindEmptySides() { IList <int> indicies = new List <int>(); Tic side2 = _board.Get(2); if (side2 == Tic.None) { indicies.Add(2); } Tic side4 = _board.Get(4); if (side4 == Tic.None) { indicies.Add(4); } Tic side6 = _board.Get(6); if (side6 == Tic.None) { indicies.Add(6); } Tic side8 = _board.Get(8); if (side8 == Tic.None) { indicies.Add(8); } return(indicies); }
private void HandleTicsZ() { if (graph.zTicStep <= 0) { return; } //Make missing tics //Above zero float i = graph.zTicStep; while (i <= graph.zMax) { bool exists = false; foreach (Tic tic in zTics) { if (tic.value == i) { exists = true; } } if (exists == false) { Tic newTic = Instantiate(ticPrefab, zAxisMasterContainer.transform); newTic.graph = this.graph; newTic.axis = "z"; newTic.value = i; newTic.SetPosition(); zTics.Add(newTic); newTic.MakeLabel(); newTic.ScaleUpFromZero(); } i += graph.zTicStep; } //Below zero i = -graph.zTicStep; while (i >= graph.zMin) { bool exists = false; foreach (Tic tic in zTics) { if (tic.value == i) { exists = true; } } if (exists == false) { Tic newTic = Instantiate(ticPrefab, zAxisMasterContainer.transform); newTic.graph = this.graph; newTic.axis = "z"; newTic.value = i; newTic.SetPosition(); zTics.Add(newTic); newTic.MakeLabel(); newTic.ScaleUpFromZero(); } i -= graph.zTicStep; } }
// Center: A player marks the center. (If it is the first move of the game, playing on a corner gives the second player more opportunities to make a mistake and may therefore be the better choice; however, it makes no difference between perfect players.) private int FindCenter() { Tic center = _board.Get(5); if (center == Tic.None) { return(5); } return(0); }
private bool SetCell(Cell cell, Tic value) { if (cell.Value == Tic.None) { cell.Value = value; return(true); } else { System.Diagnostics.Trace.WriteLine($"Cell is already set."); return(false); } }
public bool Set(int cellIndex, Tic tic) { if (!IsIndexValid(cellIndex)) { return(false); } System.Diagnostics.Trace.WriteLine($"Trying to set {cellIndex} to {tic}"); bool success = SetCell(cells[cellIndex - 1], tic); System.Diagnostics.Trace.WriteLineIf(success, $"Set {cellIndex} to {tic}"); return(success); }
private int FindNoneIndexWhenTheOtherMatchs(int position1, int position2, Tic match) { Tic corner1Tic = _board.Get(position1); Tic corner2Tic = _board.Get(position2); if (corner1Tic == match && corner2Tic == Tic.None) { return(position2); } if (corner2Tic == match && corner1Tic == Tic.None) { return(position1); } return(0); }
private bool FindNonCornerFork(int nonCornerIndex, int row2, int row3, int col2, int col3, Tic find) { Tic corner = _board.Get(nonCornerIndex); if (corner == Tic.None) { int rowNoneIndex = FindNoneIndexWhenTheOtherMatchs(row2, row3, find); int colNoneIndex = FindNoneIndexWhenTheOtherMatchs(col2, col3, find); if (rowNoneIndex > 0 && colNoneIndex > 0) { return(true); } } return(false); }
// Opposite corner: If the opponent is in the corner, the player plays the opposite corner. private IList <int> FindOppositeCorners() { IList <int> indicies = new List <int>(); Tic opponent = _thisPlayer.FindOpponent(); int cross1Corner = FindNoneIndexWhenTheOtherMatchs(1, 9, opponent); indicies.AddIfNotZero(cross1Corner); int cross2Corner = FindNoneIndexWhenTheOtherMatchs(3, 7, opponent); indicies.AddIfNotZero(cross2Corner); return(indicies); }
public bool Play(int cellIndex) { if (_currentPlayer != Tic.None) { bool success = _board.Set(cellIndex, _currentPlayer); if (success) { _currentPlayer = _currentPlayer.FindOpponent(); } return(success); } else { return(false); } }
private Tic?CheckLine(Tic _1, Tic _2, Tic _3) { if (_1 != Tic.None && _2 != Tic.None && _3 != Tic.None) { if (_1 == _2 && _2 == _3) { return(_1); // all three match, so return the match } else { return(Tic.None); // all threee are claimed, but neither side has all three, so no one wins. } } else { return(null); // at least one is not claimed, so there is no result. } }
private Status CheckForWinner(Tic _1, Tic _2, Tic _3) { Tic? lineResult = CheckLine(_1, _2, _3); Status status = new Status(); if (lineResult.HasValue) { if (lineResult.Value != Tic.None) { _gameOver = true; status.WinnerFound = lineResult.Value; } else { status.NoWinnerPossible = true; } } return(status); }
private int FindEmptyIndexInALineWithTwoMatching(int cell1, int cell2, int cell3, Tic find) { Tic cell1Value = _board.Get(cell1); Tic cell2Value = _board.Get(cell2); Tic cell3Value = _board.Get(cell3); if (cell1Value == find && cell2Value == find && cell3Value == Tic.None) { return(cell3); } if (cell1Value == find && cell2Value == Tic.None && cell3Value == find) { return(cell2); } if (cell1Value == Tic.None && cell2Value == find && cell3Value == find) { return(cell1); } return(0); }
// Win: If the player has two in a row, they can place a third to get three in a row. // Block: If the opponent has two in a row, the player must play the third themselves to block the opponent. private IList <int> FindWinOrBlock(Tic find) { IList <int> indicies = new List <int>(); int row1Index = FindEmptyIndexInALineWithTwoMatching(1, 2, 3, find); indicies.AddIfNotZero(row1Index); int row2Index = FindEmptyIndexInALineWithTwoMatching(4, 5, 6, find); indicies.AddIfNotZero(row2Index); int row3Index = FindEmptyIndexInALineWithTwoMatching(7, 8, 9, find); indicies.AddIfNotZero(row3Index); int col1Index = FindEmptyIndexInALineWithTwoMatching(1, 4, 7, find); indicies.AddIfNotZero(col1Index); int col2Index = FindEmptyIndexInALineWithTwoMatching(2, 5, 8, find); indicies.AddIfNotZero(col2Index); int col3Index = FindEmptyIndexInALineWithTwoMatching(3, 6, 9, find); indicies.AddIfNotZero(col3Index); int cross1Index = FindEmptyIndexInALineWithTwoMatching(1, 5, 9, find); indicies.AddIfNotZero(cross1Index); int cross2Index = FindEmptyIndexInALineWithTwoMatching(3, 5, 7, find); indicies.AddIfNotZero(cross2Index); return(indicies); }
// Fork: Create an opportunity where the player has two threats to win (two non-blocked lines of 2). // Blocking an opponent's fork: If there is only one possible fork for the opponent, the player should block it. // ** Otherwise, the player should block any forks in any way that simultaneously allows them to create two in a row. // ** Otherwise, the player should create a two in a row to force the opponent into defending, as long as it doesn't result in them creating a fork. For example, if "X" has two opposite corners and "O" has the center, "O" must not play a corner in order to win. (Playing a corner in this scenario creates a fork for "X" to win.) // HACK: Need to add the above **. private IList <int> FindForks(Tic find) { IList <int> indicies = new List <int>(); bool corner1Fork = FindCornerFork(1, 2, 3, 9, 4, 7, find); if (corner1Fork) { indicies.Add(1); } bool corner3Fork = FindCornerFork(3, 1, 2, 7, 6, 9, find); if (corner3Fork) { indicies.Add(3); } bool corner7Fork = FindCornerFork(7, 8, 9, 3, 4, 1, find); if (corner7Fork) { indicies.Add(7); } bool corner9Fork = FindCornerFork(9, 7, 8, 1, 6, 3, find); if (corner9Fork) { indicies.Add(9); } bool edge2Fork = FindNonCornerFork(2, 1, 3, 5, 8, find); if (edge2Fork) { indicies.Add(2); } bool edge4Fork = FindNonCornerFork(4, 5, 6, 1, 7, find); if (edge4Fork) { indicies.Add(4); } bool edge6Fork = FindNonCornerFork(6, 4, 5, 3, 9, find); if (edge6Fork) { indicies.Add(6); } bool edge8Fork = FindNonCornerFork(8, 7, 9, 2, 5, find); if (edge8Fork) { indicies.Add(8); } bool centerFork = FindNonCornerFork(5, 4, 6, 2, 8, find); if (centerFork) { indicies.Add(5); } return(indicies); }
public void StartNew() { _board.Clear(); _currentPlayer = Tic.X; _gameOver = false; }
private Tic?IfThereIsAWinnerWhoIsIt() { Tic _1 = _board.Get(1); Tic _2 = _board.Get(2); Tic _3 = _board.Get(3); Tic _4 = _board.Get(4); Tic _5 = _board.Get(5); Tic _6 = _board.Get(6); Tic _7 = _board.Get(7); Tic _8 = _board.Get(8); Tic _9 = _board.Get(9); Status row1Status = CheckForWinner(_1, _2, _3); if (row1Status.WinnerFound != Tic.None) { return(row1Status.WinnerFound); } Status row2Status = CheckForWinner(_4, _5, _6); if (row2Status.WinnerFound != Tic.None) { return(row2Status.WinnerFound); } Status row3Status = CheckForWinner(_7, _8, _9); if (row3Status.WinnerFound != Tic.None) { return(row3Status.WinnerFound); } Status col1Status = CheckForWinner(_1, _4, _7); if (col1Status.WinnerFound != Tic.None) { return(col1Status.WinnerFound); } Status col2Status = CheckForWinner(_2, _5, _8); if (col2Status.WinnerFound != Tic.None) { return(col2Status.WinnerFound); } Status col3Status = CheckForWinner(_3, _6, _9); if (col3Status.WinnerFound != Tic.None) { return(col3Status.WinnerFound); } Status cross1Status = CheckForWinner(_1, _5, _9); if (cross1Status.WinnerFound != Tic.None) { return(cross1Status.WinnerFound); } Status cross2Status = CheckForWinner(_3, _5, _7); if (cross2Status.WinnerFound != Tic.None) { return(cross2Status.WinnerFound); } if (row1Status.NoWinnerPossible && row2Status.NoWinnerPossible && row3Status.NoWinnerPossible && col1Status.NoWinnerPossible && col2Status.NoWinnerPossible && col3Status.NoWinnerPossible && cross1Status.NoWinnerPossible && cross2Status.NoWinnerPossible) { _gameOver = true; return(Tic.None); } else { return(null); } }
public void HandleTicsY() { if (graph.yTicStep <= 0) { return; } if (!graph.manualTicMode) { List <Tic> toRemove = new List <Tic>(yTics); //Make missing tics //Above zero float i = graph.yTicStep; while (i <= graph.yMax) { bool exists = false; foreach (Tic tic in yTics) { if (tic.value == i) { exists = true; toRemove.Remove(tic); } } if (exists == false) { Tic newTic = Instantiate(ticPrefab, yAxisMasterContainer.transform); newTic.graph = this.graph; newTic.axis = "y"; newTic.value = i; newTic.SetPosition(); yTics.Add(newTic); newTic.MakeLabel(); newTic.ScaleUpFromZero(); } i += graph.yTicStep; } //Below zero i = -graph.yTicStep; while (i >= graph.yMin) { bool exists = false; foreach (Tic tic in yTics) { if (tic.value == i) { exists = true; toRemove.Remove(tic); } } if (exists == false) { Tic newTic = Instantiate(ticPrefab, yAxisMasterContainer.transform); newTic.graph = this.graph; newTic.axis = "y"; newTic.value = i; newTic.SetPosition(); yTics.Add(newTic); newTic.MakeLabel(); newTic.ScaleUpFromZero(); } i -= graph.yTicStep; } foreach (Tic tic in toRemove) { yTics.Remove(tic); //Hacky way of destroying ones that are gone without a coroutine if (tic.transform.localScale == Vector3.zero) { Destroy(tic); } else { tic.ScaleDownToZero(); } } } else //Manual tic mode { foreach (KeyValuePair <float, string> entry in graph.manualTicsY) { bool exists = false; foreach (Tic tic in xTics) { if (tic.value == entry.Key) { exists = true; } } if (exists == false) { Tic newTic = Instantiate(ticPrefab, xAxisMasterContainer.transform); newTic.graph = this.graph; newTic.axis = "y"; newTic.value = entry.Key; newTic.SetPosition(); yTics.Add(newTic); newTic.MakeLabel(entry.Value); newTic.ScaleUpFromZero(); } } } }
public static Tic FindOpponent(this Tic player) { return(player == Tic.X ? Tic.O : Tic.X); }
public CompPlayer(Board board, Tic thisPlayer) { _board = board; _thisPlayer = thisPlayer; }
public Cell(Tic initValue) => _value = initValue;
public int GetNextMove() { Tic opponent = _thisPlayer.FindOpponent(); IList <int> nextMove = FindWinOrBlock(_thisPlayer); if (nextMove.Count > 0) { int position1 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found a win: {position1}"); return(position1); } nextMove = FindWinOrBlock(opponent); if (nextMove.Count > 0) { int position2 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found a block: {position2}"); return(position2); } nextMove = FindForks(_thisPlayer); if (nextMove.Count > 0) { int position3 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found a fork: {position3}"); return(position3); } nextMove = FindForks(opponent); if (nextMove.Count > 0) { int position4 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found a block fork: {position4}"); return(position4); } int center = FindCenter(); if (center != 0) { Console.WriteLine($"{_thisPlayer} found the center: 5"); return(center); } nextMove = FindOppositeCorners(); if (nextMove.Count > 0) { int position5 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found an opposite corner: {position5}"); return(position5); } nextMove = FindEmptyCorners(); if (nextMove.Count > 0) { int position6 = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found an empty corner: {position6}"); return(position6); } nextMove = FindEmptySides(); int position = nextMove.GetOneAtRandom(); Console.WriteLine($"{_thisPlayer} found an empty side: {position}"); return(position); }