/// <param name="gridPos">Where the placing is examined in gridpos</param> /// <returns>Whether the user can place at gridPos</returns> public bool CanPlaceAt(int[] gridPos) { // Game has not started, explained in GameLogic CellHolder ch = GetCellHolderAtGridPos(gridPos); if (!gameLogic.GameSarted) { return(ch == null || !ch.IsDisabled); } if (ch != null && ch.IsDisabled) { return(false); } CellHolder[] holders = GetAllNeighbourCellHolders(gridPos); foreach (CellHolder holder in holders) { if (holder != null && !holder.IsDisabled && holder.IsFull()) { return(true); } } return(false); }
/// <summary> /// The neighbours are in this order: Top Right Bottom Left /// </summary> /// <param name="gridPos">The gridpos of the cell of which we want the neighbours</param> /// <returns>An array with a length of 4 in the order seen above</returns> public CellHolder[] GetNeighbourCellHolders(int[] gridPos) { CellHolder[] holders = new CellHolder[4]; holders[0] = GetUpwardCellHolder(gridPos); holders[1] = GetRightCellHolder(gridPos); holders[2] = GetDownwardCellHolder(gridPos); holders[3] = GetLeftCellHolder(gridPos); return(holders); }
public override bool Equals(object obj) { if (obj is CellHolder) { CellHolder ch = (CellHolder)obj; return(ch.WorldPos[0] == WorldPos[0] && ch.WorldPos[1] == WorldPos[1]); } return(base.Equals(obj)); }
/// <summary> /// Returns all cellholder which has signs in this partion /// </summary> /// <returns></returns> public CellHolder[] GetAllCellsWhichHaveSigns() { CellHolder[] holder = new CellHolder[hasSign.Count]; for (int i = 0; i < hasSign.Count; i++) { holder[i] = cells[hasSign[i][0], hasSign[i][1]]; } return(holder); }
/// <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)); }
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == HEADER_ITEM) { var headerView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.HeaderLayout, parent, false); var headerHolder = new HeaderHolder(headerView); return(headerHolder); } var cellView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.CellLayout, parent, false); var cellHolder = new CellHolder(cellView); return(cellHolder); }
// ______________________ Constructor __________________________ // Requieres the partion's world pos /// <param name="partionPos">Partion's world pos</param> public Partion(int[] partionPos) { this.partionPos = partionPos; cells = new CellHolder[WIDTH_HEIGHT, WIDTH_HEIGHT]; for (int i = 0; i < WIDTH_HEIGHT; i++) { for (int k = 0; k < WIDTH_HEIGHT; k++) { int[] localPos = new int[] { i, k }; cells[i, k] = new CellHolder(GetWorldCellPos(localPos)); } } }
/// <summary> /// Removes the sign we last placed /// </summary> public virtual bool RemoveLastSign() { if (numberOfSignsInGame < 1 || removeCount > 0) { return(false); // Only remove if we placed two signs already } // Remove sign CellHolder cellHolder = GetCellHolderAtGridPos(previousGridPos); if (!cellHolder.IsFull()) { return(false); // Return if we don't have a sign there } // At this point we surely are going to remove the sign if (SignWasRemovedEvent != null) { SignWasRemovedEvent(previousGridPos); } cellHolder.RemoveCurrentCellWithoutStoring(); // move marker, do this before changin turns because we want the color to be the exact opposite of the sign at secondToPrevious pos if (lastPlacedMarker != null) { lastPlacedMarker.MoveMarkerTo(new Vector2(secondToPreviousGridPos[0], secondToPreviousGridPos[1]), SignResourceStorage.Instance.GetColorRelatedTo(gameLogic.WhoseTurn)); } // Revert back to previous turn in gamelogic gameLogic.SetPreviousTurn(); // The order of these are very crucial // We just strated a game so we want to restart it if (numberOfSignsInGame == 1) { gameLogic.RestartCurrentGame(); previousGridPos = null; } else { previousGridPos[0] = secondToPreviousGridPos[0]; previousGridPos[1] = secondToPreviousGridPos[1]; } numberOfSignsInGame--; removeCount++; return(true); }
/// <summary> /// The neighbours start from bottomleft and go first right then up in rows /// </summary> /// <param name="gridPos">The gridpos of the cell of which we want the neighbours</param> /// <returns>An array with a length of 8 in the order seen above</returns> public CellHolder[] GetAllNeighbourCellHolders(int[] gridPos) { CellHolder[] neighbours = new CellHolder[8]; int at = 0; for (int i = -1; i <= 1; i++) { for (int k = -1; k <= 1; k++) { if (!(k == 0 && i == 0)) // We don't want to return the cell itself { neighbours[at] = GetCellHolderRelativeTo(gridPos, i, k); at++; } } } return(neighbours); }
/// <summary> /// Disables int the local gameField the points, which are disabled in grid<para /> /// Requires the (0,0) point in gridPos of the gameField /// </summary> private void SetLocalGridDisabled(int[] zerozero) { for (int i = 0; i < gameField.GetLength(0); i++) { for (int k = 0; k < gameField.GetLength(1); k++) { if (i == gameField.GetLength(0) / 2 && k == gameField.GetLength(1) / 2) { continue; } CellHolder ch = grid.GetCellHolderAtGridPos(new int[] { zerozero[0] + i, zerozero[1] + k }); if (!(ch == null || ch.CurrentTemplate.cellOcc == Cell.CellOcc.NONE)) { gameField[i, k].type = Cell.CellOcc.BLOCKED; // Because it checks for NONEs in algorithm } } } }
/// <summary> /// Returns whether someone has won the game based on the placement of a sign /// So it should be called after a sign has been placed /// </summary> /// <param name="gridPos">Where the sign has been placed</param> /// <returns>Returns BLOCKED when no one won yet</returns> public TTTGameLogic.GameWonData DidWinGame(int[] gridPos) { CellHolder currCellHolder = GetCellHolderAtGridPos(gridPos); Cell.CellOcc currCellType = currCellHolder.CurrentTemplate.cellOcc; // Used for return data TTTGameLogic.GameWonData gameWonData = new TTTGameLogic.GameWonData(); CellHolder[] winCells = new CellHolder[WIN_CONDITION]; winCells[0] = currCellHolder; // Go through directions for (int i = 0; i <= 1; i++) { for (int k = -1; k <= 1; k++) { if (!(k == 0 && i == 0) && !(i == 0 && k == 1)) // Dont want 0 0 direction or up dir { int count = 1; // Used to determine whether someone has won: if after the loop it is WIN_CONDITION someone has won // Go till we found end in this direction or founf out that someone has won for (int j = 1; j < WIN_CONDITION && count < WIN_CONDITION; j++) { CellHolder ch = GetCellHolderRelativeTo(gridPos, i * j, k * j); // ch is null // OR ch is not full // OR ch is disabled // OR cell type is not the one we have in this cell if (!(ch != null && ch.IsFull() && !ch.IsDisabled && ch.CurrentTemplate.cellOcc == currCellType)) { break; } winCells[count] = ch; count++; } // We need to go in the other direction as well for (int j = 1; j < WIN_CONDITION && count < WIN_CONDITION; j++) { CellHolder ch = GetCellHolderRelativeTo(gridPos, -i * j, -k * j); // ch is null // OR ch is not full // OR ch is disabled // OR cell type is not the one we have in this cell if (!(ch != null && ch.IsFull() && !ch.IsDisabled && ch.CurrentTemplate.cellOcc == currCellType)) { break; } winCells[count] = ch; count++; } if (count >= WIN_CONDITION) { gameWonData.gameWon = true; gameWonData.winType = currCellType; gameWonData.HoldersWithWon = winCells; return(gameWonData); } } } } gameWonData.gameWon = false; return(gameWonData); }
/// <summary> /// It disables all of the sign which belong to this game /// </summary> /// <param name="wonData">More data like cellgrid of current game pass in a wonData</param> public TTTGameLogic.GameWonData StopCurrentGame(TTTGameLogic.GameWonData wonData) { // We need to start a bejaras from the last placed sign's pos, which we happen to store in previousGridPos // Then set all of the found sign's cellholder to disabled // Disable marker if (lastPlacedMarker != null) { lastPlacedMarker.Disable(); } // Ended game so reset the amount of cells in game numberOfSignsInGame = 0; // Store all of the cellholders which have signs in game List <CellHolder> listOfCells = new List <CellHolder>(); listOfCells.Add(GetCellHolderAtGridPos(previousGridPos)); Queue <CellHolder> queue = new Queue <CellHolder>(); queue.Enqueue(listOfCells[0]); // Stores the min and max values of x and y (essentially bottomleft and topright corner points) int[] min = new int[] { int.MaxValue, int.MaxValue }; int[] max = new int[] { int.MinValue, int.MinValue }; // Go through cells in this game while (queue.Count > 0) { CellHolder currCH = queue.Dequeue(); if (currCH.IsDisabled) { break; } // Store the min and max of x and y we examine if (currCH.WorldPos[0] < min[0]) { min[0] = currCH.WorldPos[0]; } if (currCH.WorldPos[0] > max[0]) { max[0] = currCH.WorldPos[0]; } if (currCH.WorldPos[1] < min[1]) { min[1] = currCH.WorldPos[1]; } if (currCH.WorldPos[1] > max[1]) { max[1] = currCH.WorldPos[1]; } // Disable cell currCH.Disable(); // Get all af nthe neighbours af current cell CellHolder[] neighbours = GetAllNeighbourCellHolders(currCH.WorldPos); foreach (CellHolder ch in neighbours) { if (ch != null && !ch.IsDisabled && ch.IsFull()) // Found a cell which belongs to this game { if (!queue.Contains(ch) && !listOfCells.Contains(ch)) { queue.Enqueue(ch); listOfCells.Add(ch); } } } } wonData.table = new bool[Mathf.Abs(max[0] - min[0] + 1), Mathf.Abs(max[1] - min[1] + 1)]; // Fill the thingy with true where there is a cell. Thingy defined in WonData class foreach (CellHolder ch in listOfCells) { wonData.table[ch.WorldPos[0] - min[0], ch.WorldPos[1] - min[1]] = true; } wonData.startPos = min; // Now we can fill the holes List <int[]> holes = wonData.GetFillableHoles(); foreach (int[] pos in holes) { // Get the partion the cell is in (we surely have this one, because holes are between signs int[] partionPos = Partion.GetPartionPosOfCell(pos); Partion p; // We don't have a partion yet for this pos if (!partions.ContainsKey(partionPos)) { p = new Partion(partionPos); partions.Add(partionPos, p); } else // we already store the partion in the dictionary { partions.TryGetValue(partionPos, out p); } // Place new BLOCKED cell in partion at pos p.PlaceSign(Partion.GetLocalPosOfCell(pos), Cell.CellOcc.BLOCKED, true); } return(wonData); }