/// <summary> /// Called when someone won the game on AI screen /// </summary> private static void GameWonAI(Cell.CellOcc type) { AIScript ai = GameObject.FindObjectOfType <AIScript>(); IncrementAchievement(achievementTenGamesAgainstAi); IncrementAchievement(achievementFiftyGamesAgainstAi); IncrementAchievement(achievement100GamesAgainstAi); IncrementAchievement(achievement1000GamesAgainstTheAi); // Player won if (type != AIScript.AIType) { IncrementAchievement(achievement10WinsAgainstTheAi); IncrementAchievement(achievement50WinsAgainstTheAi); IncrementAchievement(achievement100WinsAgainstTheAi); IncrementAchievement(achievement250WinsAgainstTheAi); IncrementAchievement(achievement1000WinsAgainstTheAi); // won against hard difficulty if (ai.Difficulty == 3) { IncrementAchievement(achievementWin50TimesAgainstHardAi); IncrementAchievement(achievementWin250TimesAgainstTheHardAi); IncrementAchievement(achievementWin1000TimesAgainstTheHardAi); } } GameWon(type); }
/// <summary> /// Adds a point to both the gameField and pointsingame list /// </summary> /// <param name="pos"></param> private void AddPoint(IntVector2 pos, Cell.CellOcc type) { // We already have a pos there so just return // This shouldn't happen but just in case it does we are ready if (gameField[pos.x, pos.y].type != Cell.CellOcc.NONE) { return; } gameField[pos.x, pos.y].type = type; pointsInGame.Add(pos); // Set the bound of our game correctly if (pos.x < bottomLeftPosOfField.x) { bottomLeftPosOfField.x = pos.x; } if (pos.y < bottomLeftPosOfField.y) { bottomLeftPosOfField.y = pos.y; } if (pos.x > topRightPosOfField.x) { topRightPosOfField.x = pos.x; } if (pos.y > topRightPosOfField.y) { topRightPosOfField.y = pos.y; } List <PlaceData> placeData; NewSignPlaced(gameField, pos, out placeData, out placeData); }
public override void NextTurn(int[] gridPos, out Cell.CellOcc won) { base.NextTurn(gridPos, out won); // If no one has won and it is AI's turn make AI place if (won == Cell.CellOcc.BLOCKED && whoseTurn == AIScript.AIType) { AIsTurn(); } else if (whoseTurn == AIScript.AIType && won != Cell.CellOcc.BLOCKED) // if player has won put a delay before AI puts { Invoke("AiPlaceRandom", 3f); } // Set points if (won == AIScript.AIType) { aiPoint++; } else if (won == AIScript.HumanType) { humanPoint++; } if (AIScript.AIType == Cell.CellOcc.X) { scoring.SetScore(aiPoint, humanPoint); } else { scoring.SetScore(humanPoint, aiPoint); } }
public static void AddBorderPoints(int[,] points, float[,] winLinePoints, Cell.CellOcc winType) { BorderStorageLogic b = new BorderStorageLogic(points, winLinePoints, winType); bordersNotShown.Add(b); MoveToShown(bordersNotShown.Count - 1); }
/// <summary> /// DYDD<para /> /// DYXD<para /> /// DYYD<para /> /// All ys are smaller than x<para /> /// Always sets the smaller of the to vectors to be in the from vector<para /> /// Also sets the steepness as well<para /> /// Also updates points and length<para /> /// </summary> public void SetPoints(IntVector2 from, IntVector2 to, Cell.CellOcc type) { if (from.y == to.y) { if (from.x < to.x) { this.from = new IntVector2(from); this.to = new IntVector2(to); } else { this.from = new IntVector2(to); this.to = new IntVector2(from); } } else { if (from.y < to.y) { this.from = new IntVector2(from); this.to = new IntVector2(to); } else { this.from = new IntVector2(to); this.to = new IntVector2(from); } } steepness = new IntVector2((this.to.x - this.from.x), (this.to.y - this.from.y)); steepness = steepness / Mathf.Max(Mathf.Abs(steepness.x), Mathf.Abs(steepness.y)); }
/// <summary> /// Called from grid in event when sign was placed /// </summary> private void SignWasAdded(int[] gridPos, Cell.CellOcc type) { // first point placed in this game if (firstPointInGame == null) { gameInProgress = true; SetLocalGridDisabled(new int[] { gridPos[0] - gameField.GetLength(0) / 2, gridPos[1] - gameField.GetLength(1) / 2 }); } // Set the all bounds if needed if (gridPos[0] < bottomLeftAll.x) { bottomLeftAll.x = gridPos[0]; } if (gridPos[1] < bottomLeftAll.y) { bottomLeftAll.y = gridPos[1]; } if (gridPos[0] > topRightAll.x) { topRightAll.x = gridPos[0]; } if (gridPos[1] > topRightAll.y) { topRightAll.y = gridPos[1]; } IntVector2 pos = GridToLocalAIPos(gridPos); AddPoint(pos, type); }
public virtual void Start() { // It needs to be in start because we create the gridmanager object in start and so // in Execution Order i've set it so this comes after that grid = FindObjectOfType<Grid>(); // Set whoseturn to a random one whoseTurn = Random.Range(0, 2) == 0 ? Cell.CellOcc.X : Cell.CellOcc.O; }
public void PlayRandomSoundFor(AudioSource source, Cell.CellOcc type) { switch (type) { case Cell.CellOcc.X: PlayXRandomPlaceSound(source); break; case Cell.CellOcc.O: PlayORandomPlaceSound(source); break; } }
public override void Start() { grid = FindObjectOfType <GPGrid>(); scoring = FindObjectOfType <ScoringScript>(); serverType = Cell.CellOcc.X; whoseTurn = Cell.CellOcc.X; SomeoneWonGameEvent += SomeOneWonGame; }
/// <summary> /// Creates a new cell in this holder of type celltype. /// If type is blocked then it's gonna disable cell by default and the returned cell will be null /// </summary> /// <param name="cellType"></param> /// <param name="animate">Whether to animate the cell or not</param> /// <returns>Return null if the cell could not be created</returns> public Cell NewCell(Cell.CellOcc cellType, bool animate = true) { if (!cell) { // We have a blocking cell, for example a hole filler if (cellType == Cell.CellOcc.BLOCKED) { Disable(); currentTemplate = new CellTemplate(); currentTemplate.cellOcc = cellType; return(null); } cellGameObject = CellPooling.GetCell(); SpriteRenderer sprR = cellGameObject.GetComponent <SpriteRenderer>(); sprR.sortingLayerName = "Signs" + cellType.ToString(); // Set sorting layer for dynamic batching sprR.color = SignResourceStorage.Instance.GetColorRelatedTo(cellType); if (Grid.cellParent != null) { cellGameObject.transform.parent = Grid.cellParent.transform; } // current cell template currentTemplate = new CellTemplate(); currentTemplate.cellOcc = cellType; // Set cell type both for animation and data storage purposes cell = cellGameObject.GetComponent <Cell>(); cell.cellType = cellType; // Animation if (animate) { cell.TriggerDraw(); } else { cell.TriggerIdle(); } // Subtract .five because the center is the pivot (because we want to rotate it to give it better look) cellGameObject.transform.position = GetRandomPosBasedOnWorldPos(); cellGameObject.transform.eulerAngles = GetRandomAngles(); } else { return(null); } return(cell); }
/// <summary> /// Add type cell at gridPos in world units locally /// </summary> public void PlaceCellAt(int[] gridPos, Cell.CellOcc type) { CellHolder ch = new CellHolder(gridPos); ch.NewCell(type); visibleCells.Add(ch); lastSign = new int[2] { gridPos[0], gridPos[1] }; lastPlaced.MoveMarkerTo(new Vector2(gridPos[0], gridPos[1]), SignResourceStorage.Instance.GetColorRelatedTo(type == Cell.CellOcc.X ? Cell.CellOcc.O : Cell.CellOcc.X)); }
protected void Update() { // We are not displaying the correct sprite on screen if (gameLogic.WhoseTurn != currentlyDisplayed) { currentlyDisplayed = gameLogic.WhoseTurn; UpdateSprite(); PlayCursorSpriteUpdateAnimation(); } }
public override bool PlaceSign(int[] gridPos, Cell.CellOcc cellType, bool disabled = false) { bool ret = base.PlaceSign(gridPos, cellType, disabled); if (ret) { lastSignType = cellType; } return(ret); }
/// <summary> /// Returns the color of the cellType /// </summary> public Color GetColorRelatedTo(Cell.CellOcc cellType) { switch (cellType) { case Cell.CellOcc.X: return(xColor); case Cell.CellOcc.O: return(oColor); } return(Color.magenta); }
/// <summary> /// Places sign at gridpos pos of type cellType /// </summary> /// <param name="gridPos">Grid pos of click</param> /// <param name="cellType"></param> /// <returns> whether the sign could be placed or not></returns> public virtual bool PlaceSign(int[] gridPos, Cell.CellOcc cellType, bool disabled = false) { // The partion's pos int[] partionPos = Partion.GetPartionPosOfCell(gridPos); // The cell's partion Partion currP; // We don't have a partion yet for this pos if (!partions.ContainsKey(partionPos)) { currP = new Partion(partionPos); partions.Add(partionPos, currP); } else // we already store the partion in the dictionary { partions.TryGetValue(partionPos, out currP); } // At this point we should surely have the partion in p // We need to convert the click's world pos to partion local pos int[] localPos = Partion.GetLocalPosOfCell(gridPos); // We need to place the sign in the partion bool couldBePlaced = currP.PlaceSign(localPos, cellType, disabled); if (couldBePlaced && !disabled) // If we could place the sign store it's gridPos { if (previousGridPos != null) { secondToPreviousGridPos = new int[] { previousGridPos[0], previousGridPos[1] } } ; previousGridPos = new int[] { gridPos[0], gridPos[1] }; // Increase amount of cells in game numberOfSignsInGame++; removeCount = 0; // Reset removecount to be able to remove sign again // move marker if (lastPlacedMarker != null) { lastPlacedMarker.MoveMarkerTo(new Vector2(gridPos[0], gridPos[1]), SignResourceStorage.Instance.GetColorRelatedTo(gameLogic.WhoseTurn == Cell.CellOcc.X ? Cell.CellOcc.O : Cell.CellOcc.X)); } if (SignWasPlacedEvent != null) { SignWasPlacedEvent(gridPos, cellType); } } return(couldBePlaced); }
private void SomeOneWonGame(Cell.CellOcc type) { // this device won if (type == serverType) { PreferencesScript.Instance.PullExpBarThenAdd(BluetoothTTTGameLogic.EXP_FOR_WINNING); } else { PreferencesScript.Instance.PullExpBarThenAdd(BluetoothTTTGameLogic.EXP_FOR_LOSING); } }
public void UpdateImage(Cell.CellOcc newType) { currentlyDisplayed = newType; currentSign.sprite = SignResourceStorage.Instance.GetSpriteRelatedTo(newType); currentSign.color = SignResourceStorage.Instance.GetColorRelatedTo(newType); if (newType != currentlyDisplayed) { PlayCursorSpriteUpdateAnimation(); } }
/// <summary> /// Returns: X -> O ; O -> X ; other -> NONE /// </summary> /// <param name="cellType"></param> /// <returns></returns> public static Cell.CellOcc GetOppositeOfSign(Cell.CellOcc cellType) { if (cellType == Cell.CellOcc.X) { return(Cell.CellOcc.O); } else if (cellType == Cell.CellOcc.O) { return(Cell.CellOcc.X); } return(Cell.CellOcc.NONE); }
/// <summary> /// Event for when someone has won the game /// </summary> private void SomeoneWonGame(Cell.CellOcc type) { gameInProgress = false; if (type == HumanType) { PreferencesScript.Instance.PullExpBarThenAdd((int)GetGameWonExp()); } else { PreferencesScript.Instance.PullExpBarThenAdd((int)GetGameLostExp()); } }
/// <summary> /// Return sprite related to the cellocc /// </summary> /// <param name="cellType"></param> /// <returns>may return null</returns> public Sprite GetSpriteRelatedTo(Cell.CellOcc cellType) { switch (cellType) { case Cell.CellOcc.X: return(xSprite); case Cell.CellOcc.O: return(oSprite); default: return(null); } }
/// <summary> /// Called when someone won the game /// </summary> private static void GameWon(Cell.CellOcc type) { // Player hasn't won yet if (PlayerPrefs.GetInt(achievementFirstWin) == 0) { UnlockAchievement(achievementFirstWin); } IncrementAchievement(achievementPlay50Games); IncrementAchievement(achievementPlay100Games); IncrementAchievement(achievementPlay500Games); IncrementAchievement(achievementPlay1000Games); IncrementAchievement(achievementPlay5000Games); IncrementAchievement(achievementPlay10000Games); }
public BorderStorageLogic(int[,] points, float[,] winLinePoints, Cell.CellOcc winType) { minPos = new int[2]; minPos[0] = int.MaxValue; minPos[1] = int.MaxValue; maxPos = new int[2]; maxPos[0] = int.MinValue; maxPos[1] = int.MinValue; middlePos = new int[2]; this.winType = winType; this.winLinePoints = winLinePoints; this.points = points; CalculateMinMaxPos(); }
// Called when someone wins the game public void SomeoneWon(Cell.CellOcc type) { if (SomeoneWonEvent != null) { SomeoneWonEvent(type); } // Not this device won if (type == BluetoothTTTGameLogic.serverType) { PreferencesScript.Instance.PullExpBarThenAdd(BluetoothTTTGameLogic.EXP_FOR_LOSING); } else { PreferencesScript.Instance.PullExpBarThenAdd(BluetoothTTTGameLogic.EXP_FOR_WINNING); } }
/// <summary> /// Read from FILE_PATH the stored data /// </summary> public static void ReadBordersFromFile() { // Order of data written in WriteBorder Method try { string[] lines = System.IO.File.ReadAllLines(FILE_PATH); if (lines.Length == 0) { return; } int count = int.Parse(lines[0]); string[] line; for (int i = 0; i < count; i++) { line = lines[1 + 2 * i].Split(' '); string s = ""; int[,] points = new int[int.Parse(line[0]), 2]; int at = 1; for (int k = 0; k < points.GetLength(0); k++) { points[k, 0] = int.Parse(line[at]); points[k, 1] = int.Parse(line[at + 1]); s += line[at] + " " + line[at + 1] + " "; at += 2; } Cell.CellOcc winType = (Cell.CellOcc)Enum.Parse(typeof(Cell.CellOcc), line[line.Length - 1]); line = lines[2 + 2 * i].Split(' '); float[,] winLinePoints = new float[2, 2]; for (int k = 0; k < winLinePoints.GetLength(0); k++) { for (int j = 0; j < winLinePoints.GetLength(1); j++) { winLinePoints[k, j] = float.Parse(line[k * 2 + j]); } } bordersNotShown.Add(new BorderStorageLogic(points, winLinePoints, winType)); } } catch (Exception e) { Debug.LogError(e.Message); } }
public override void NextTurn(int[] gridPos, out Cell.CellOcc won) { Cell.CellOcc didWin; base.NextTurn(gridPos, out didWin); if (didWin == Cell.CellOcc.X) { xScore++; scoring.SetScore(xScore, oScore); } else if (didWin == Cell.CellOcc.O) { oScore++; scoring.SetScore(xScore, oScore); } won = didWin; }
/// <summary> /// Sets the whoseturn correctly and handles winning condition /// </summary> /// <param name="gridPos">Where the previous sign has been placed</param> public virtual void NextTurn(int[] gridPos, out Cell.CellOcc won) { NextPerson(); // Check whether someone has won GameWonData cellWon = grid.DidWinGame(gridPos); // Someone has won if (cellWon.gameWon) { cellWon = grid.StopCurrentGame(cellWon); gameStarted = false; if (SomeoneWonGameEvent != null) SomeoneWonGameEvent(cellWon.winType); StartCoroutine("DrawBorderToGame", cellWon); } won = cellWon.gameWon ? cellWon.winType : Cell.CellOcc.BLOCKED; }
private IntVector2 WhichIsBetter(IntVector2 first, IntVector2 second, Cell.CellOcc placeType) { float[] points = new float[2]; for (int j = 0; j < 2; j++) { IntVector2 pos = j == 0 ? first : second; // Data so we can revert the field back (because recursive algorithm) List <PlaceData> placed; List <PlaceData> removed; // Set the examined cell to the current's sign gameField[pos.x, pos.y].type = placeType; NewSignPlaced(gameField, pos, out placed, out removed); pointsInGame.Add(new IntVector2(pos)); float aiPoints, humPoints; points[j] = GetPointsFromSignsInARow(gameField, pointsInGame, pos, out aiPoints, out humPoints); // Revert the field back for (int l = 0; l < placed.Count; l++) { gameField[placed[l].fieldPos.x, placed[l].fieldPos.y].signsInARow.Remove(placed[l].signInARow); } for (int l = 0; l < removed.Count; l++) { gameField[removed[l].fieldPos.x, removed[l].fieldPos.y].signsInARow.Add(removed[l].signInARow); } gameField[pos.x, pos.y].type = Cell.CellOcc.NONE; pointsInGame.RemoveAt(pointsInGame.Count - 1); } if (placeType == AIType) // We are maximizing { return(points[0] > points[1] ? first : second); } else // We are minimizing { return(points[0] > points[1] ? second : first); } }
public int BlockCount() { Cell.CellOcc oppType = SignResourceStorage.GetOppositeOfSign(type); bool block1 = blockField1.type == oppType || blockField1.type == Cell.CellOcc.BLOCKED; bool block2 = blockField2.type == oppType || blockField2.type == Cell.CellOcc.BLOCKED; if (block1 && block2) { return(2); } else if (block1 || block2) { return(1); } else { return(0); } }
private void SomeoneWonGame(Cell.CellOcc type) { if (type == AIScript.AIType) { aiWinCount++; } else { humanWinCount++; } // First win of anybody if (aiWinCount + humanWinCount == 1) { scoringRect.DOLocalMoveY(scoringRect.localPosition.y - 100, 2f); // AI won if (aiWinCount == 1) { helpText.text = "Try to prevent the AI from having three signs in a row!"; ShowThenHideHelpText(4f); } } // Player won for the first time if (humanWinCount == 1) { helpText.text = "Good job!\n Now you can go back to menu with the back button on you phone!"; ShowThenHideHelpText(5f); ScaneManager.Instance.backButtonEnabled = true; PreferencesScript.Instance.SetTutorialToCompleted(); aiScript.SetDifficulty(1); } else if (humanWinCount == 2) { aiScript.SetDifficulty(2); } }
/// <summary> /// Places a sign in the cell /// </summary> /// <param name="pos">localpartionpos of cell</param> /// <param name="cellType"></param> /// <returns>whether the sign could be placed or not</returns> public bool PlaceSign(int[] pos, Cell.CellOcc cellType, bool disabled = false) { hasSign.Add(pos); // If we want to create it disabled dont make an object at first just store a celltemplate if (disabled) { cells[pos[0], pos[1]].StoreTemplate(cellType, cells[pos[0], pos[1]].GetRandomPosBasedOnWorldPos()); cells[pos[0], pos[1]].Disable(); return(true); } Cell c = cells[pos[0], pos[1]].NewCell(cellType); // Couldn't create cell for some reason if (c == null) { return(false); } // At this point the cell was surely created return(true); }