// [2016.12.01] // [SC] place active player's tile on a board public void placePlayerTileOnBoard(int playerIndex) { if (!activeGameFlag) { return; } if (playerIndex != activePlayerIndex) { Cfg.log("It is not your turn!"); return; } Player activePlayer = players[activePlayerIndex]; // [SC] check if player can put tiles on a board if (!activePlayer.getCanMove()) { Cfg.log("Cannot move a tile after dropping a tile!"); // [TODO] return; } // [SC] check if board position is selected if (!isSelected()) { Cfg.log("Select a board position at first!"); // [TODO] return; } // [SC] check if player tile is selected if (!activePlayer.isTileSelected()) { Cfg.log("Select a tile at first!"); // [TODO] return; } TileZeroTile tile = activePlayer.getSelectedTile(); int result = putTileOnBoard(selectedRowIndex, selectedColIndex, tile, true); if (result != Cfg.NONE) { Cfg.log(String.Format(" Put tile {0} at position {1}-{2} for {3} points.", tile.ToString(), selectedRowIndex, selectedColIndex, result)); // [SC] increase player's score activePlayer.increaseScore(result); // [SC] remove the tile from the player and reset player selection activePlayer.removeSelectedTile(); // [SC] disable mismatching tiles activePlayer.disableMismatchedTiles(tile.getColorIndex(), tile.getShapeIndex()); // [SC] prevent the player from dropping tiles in the same turn activePlayer.setCanDrop(false); // [SC] reset board selection resetSelected(); } }
// [SC] returns true if this tile has the same color and shape as another tile public bool sameVisTile(TileZeroTile tile) { if (this.colorIndex == tile.getColorIndex() && this.shapeIndex == tile.getShapeIndex()) { return(true); } else { return(false); } }
////// END: functions for manipulating a selected tile ///////////////////////////////////////////////////////////////// public void disableMismatchedTiles(int colorIndex, int shapeIndex) { if (!hasColorReq() && !hasShapeReq()) { setColorReq(colorIndex); setShapeReq(shapeIndex); } else if (hasColorReq() && hasShapeReq()) { if (sameColorReq(colorIndex) && !sameShapeReq(shapeIndex)) { resetShapeReq(); } else if (!sameColorReq(colorIndex) && sameShapeReq(shapeIndex)) { resetColorReq(); } } if (hasColorReq() && hasShapeReq()) { for (int currTileIndex = 0; currTileIndex < playerTiles.Count; currTileIndex++) { TileZeroTile tile = playerTiles[currTileIndex]; if (!sameColorReq(tile.getColorIndex()) && !sameShapeReq(tile.getShapeIndex())) { tile.setPlayable(false); } } } else if (hasColorReq() && !hasShapeReq()) { for (int currTileIndex = 0; currTileIndex < playerTiles.Count; currTileIndex++) { TileZeroTile tile = playerTiles[currTileIndex]; if (!sameColorReq(tile.getColorIndex())) { tile.setPlayable(false); } } } else if (!hasColorReq() && hasShapeReq()) { for (int currTileIndex = 0; currTileIndex < playerTiles.Count; currTileIndex++) { TileZeroTile tile = playerTiles[currTileIndex]; if (!sameShapeReq(tile.getShapeIndex())) { tile.setPlayable(false); } } } }
// [2016.12.01] // [SC] a function for dropping a tile public void dropPlayerTile(int playerIndex) { if (!activeGameFlag) { return; } if (playerIndex != activePlayerIndex) { Cfg.log("It is not your turn!"); return; } Player activePlayer = players[activePlayerIndex]; // [SC] check if player drop tiles if (!activePlayer.getCanDrop()) { Cfg.log("Cannot drop a tile after putting a tile on a board!"); // [TODO] return; } // [SC] check if bag has tiles if (tileBag.Count == 0) { Cfg.log("Cannot drop a tile! The bag is empty."); // [TODO] return; } // [SC] check if player tile is selected if (!activePlayer.isTileSelected()) { Cfg.log("Select a tile at first!"); // [TODO] return; } TileZeroTile tile = activePlayer.getSelectedTile(); // [SC] make sure that the tile being dropped is not a replacement tile of previously dropped tile if (!tile.getCanDrop()) { Cfg.log("Cannot drop a replacement tile!"); return; } foreach (TileZeroTile newTile in tileBag) { // [SC] make sure that the new tile does not have the same features as the dropped tile if (newTile.getColorIndex() == tile.getColorIndex() && newTile.getShapeIndex() == tile.getShapeIndex()) { continue; } Cfg.log(String.Format(" Dropped tile {0}. Replaced with tile {1}.", tile.ToString(), newTile.ToString())); // [SC] remove the dropped tile from player's stack activePlayer.removeTile(tile); // [SC] add the dropped tile into the bag tileBag.Add(tile); // [SC] remove the new tile from the bag tileBag.Remove(newTile); // [SC] add the new tile to player's stack activePlayer.addTile(newTile); // [SC] make sure that the new tile cannot be dropped in the same turn newTile.setCanDrop(false); // [SC] shuffle the bag tileBag.Shuffle(); // [SC] prevent the player from moving tiles into the board activePlayer.setCanMove(false); break; } }
////// END: generic functions for manipulating tiles ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ////// START: functions for manipulating a selected tile private bool setSelectedTile(TileZeroTile tile) { // [TODO] make sure the tile is one of the player's tiles if (!tile.getPlayable()) { Cfg.log(String.Format("The tile {0}{1} is not playable.", tile.getColorIndex(), tile.getShapeIndex())); } else { selectedTile = tile; return(true); } return(false); }
private int isValidSequence(int rowIndex, int colIndex, int orientation, TileZeroTile[,] tileArrayP, bool showMsg) { int[] uniqueColors = new int[Cfg.MAX_VAL_INDEX]; int uniqueColorCount = 0; int[] uniqueShapes = new int[Cfg.MAX_VAL_INDEX]; int uniqueShapeCount = 0; int sequenceLength = 0; int currRow = rowIndex; int currCol = colIndex; for (int currIndex = 0; currIndex < Cfg.MAX_VAL_INDEX; currIndex++) { uniqueColors[currIndex] = Cfg.NONE; uniqueShapes[currIndex] = Cfg.NONE; } // [SC] start with the left-most or top-most tile in the sequence if (orientation == Cfg.HORIZONTAL) { while (currCol > 0 && tileArrayP[currRow, currCol - 1] != null) { currCol--; } } else { while (currRow > 0 && tileArrayP[currRow - 1, currCol] != null) { currRow--; } } // [SC] checking the validity of colors and shapes, and color-shape combination of the sequence while (currRow < rowCount && currCol < colCount) { TileZeroTile currTile = tileArrayP[currRow, currCol]; if (currTile == null) { break; } // [SC] checking the validity of colors int currColorIndex = currTile.getColorIndex(); if (uniqueColors[currColorIndex] == Cfg.NONE) { uniqueColors[currColorIndex] = currColorIndex; uniqueColorCount++; } else if (uniqueColorCount == 1) { } else { if (showMsg) { Cfg.log("Invalid color sequence."); } return(Cfg.NONE); } // [SC] checking the validity of shapes int currShapeIndex = currTile.getShapeIndex(); if (uniqueShapes[currShapeIndex] == Cfg.NONE) { uniqueShapes[currShapeIndex] = currShapeIndex; uniqueShapeCount++; } else if (uniqueShapeCount == 1) { } else { if (showMsg) { Cfg.log("Invalid shape sequence."); } return(Cfg.NONE); } sequenceLength++; if (sequenceLength > 1) { if ((uniqueColorCount == 1 && uniqueShapeCount == 1) || // [SC] both shape and color are same (uniqueColorCount > 1 && uniqueShapeCount > 1) // both shape and color are different ) { if (showMsg) { Cfg.log("Invalid combination of color and shape."); } return(Cfg.NONE); } } // [TODO] update row if (orientation == Cfg.HORIZONTAL) { currCol++; } else { currRow++; } } return(sequenceLength); }