private int totalScore; // [SC] a total score if all tiles are placed on board public CandidateTilePos(CandidateTileSeq candTileSequence, List <AbstractPos> posList, int totalScore) { this.candTileSequence = candTileSequence; this.posList = posList; this.totalScore = totalScore; candTileSequence.addCandTilePos(this); }
////// END: hard ai functionality ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ////// START: very hard ai functionality #region very hard AI public void invokeVeryHardAI() { CandidateTilePos selectedPosCombo = calculateMoves(true, true, false); if (selectedPosCombo == null) // [SC] no tiles to put on a board // [SC] dropping a random tile { setSelectedTile(playerTiles.getRandomElement()); game.dropPlayerTile(playerIndex); } else if (getCanMove()) { CandidateTileSeq tileSeq = selectedPosCombo.getCandidateTileSeq(); int totalMoveCount = selectedPosCombo.getComboLength(); int currMoveCount = 0; while (currMoveCount < totalMoveCount) { AbstractPos abstrPos = selectedPosCombo.getAbstrPosAt(currMoveCount); int rowIndex = abstrPos.getRowIndex(); int colIndex = abstrPos.getColIndex(); int tileIndex = abstrPos.getTileIndex(); TileZeroTile tile = tileSeq.getTileAt(tileIndex); setSelectedTile(tile); game.setSelectedCell(rowIndex, colIndex, playerIndex); game.placePlayerTileOnBoard(playerIndex); currMoveCount++; } } }
///////////////////////////////////////////////////////////////// ////// START: A code for creating all possible permutations of board positions ////// of tiles in given list, starting from left-most tile in the array private void boardPosPermAddChildNodes(CandidateTileSeq candTileSeq, int currTileIndex, TreeNode parentNode, TileZeroTile[,] tileArray, VirtualBoard virtualBoard) { if (currTileIndex >= candTileSeq.getTileCount()) { return; } TileZeroTile tile = candTileSeq.getTileAt(currTileIndex); for (int currRowIndex = 0; currRowIndex < tileArray.GetLength(0); currRowIndex++) { for (int currColIndex = 0; currColIndex < tileArray.GetLength(1); currColIndex++) { int resultScore = virtualBoard.isValidMove(currRowIndex, currColIndex, tile, true, tileArray, false); if (resultScore != Cfg.NONE) { TileZeroTile[,] newTileArray = Cfg.createBoardCopy(tileArray); virtualBoard.addTile(currRowIndex, currColIndex, tile, false, newTileArray); TreeNode childNode = parentNode.addChildNodeValue(new AbstractPos(currTileIndex, currRowIndex, currColIndex, resultScore)); boardPosPermAddChildNodes(candTileSeq, currTileIndex + 1, childNode, newTileArray, virtualBoard); } } } boardPosPermAddChildNodes(candTileSeq, currTileIndex + 1, parentNode, tileArray, virtualBoard); // [SC][2016.12.08] new code }
private void tileListPermTraverseTreePaths(TreeNode rootNode, List <TileZeroTile> currPath, int attrValueIndex, int attrIndex, List <CandidateTileSeq> candTileSeqList) { if (rootNode.hasChildNodes()) { List <TreeNode> childNodes = rootNode.getChildNodes(); foreach (TreeNode childNode in childNodes) { List <TileZeroTile> newPath = currPath.listShallowClone(); newPath.Add((TileZeroTile)childNode.getValue()); tileListPermTraverseTreePaths(childNode, newPath, attrValueIndex, attrIndex, candTileSeqList); } } else { ////////////////////////////////////////////////////////////////////////////// // [2016.12.08] new code CandidateTileSeq newCts = new CandidateTileSeq(attrValueIndex, attrIndex, currPath); List <CandidateTileSeq> cstToRemove = new List <CandidateTileSeq>(); bool addFlag = true; foreach (CandidateTileSeq oldCts in candTileSeqList) { // [SC] if true the new cts is a subset of existing cts if (newCts.isOrderedSubsetOf(oldCts)) { addFlag = false; break; } // [SC] if true an existing cts is a subset of the new cts else if (oldCts.isOrderedSubsetOf(newCts)) { cstToRemove.Add(oldCts); } } candTileSeqList.RemoveAll(p => cstToRemove.Contains(p)); if (addFlag) { candTileSeqList.Add(newCts); } // ////////////////////////////////////////////////////////////////////////////// } }
public bool isOrderedSubsetOf(CandidateTileSeq cts) { if (getTileCount() > cts.getTileCount()) { return(false); } else { for (int tileIndex = 0; tileIndex < getTileCount(); tileIndex++) { if (!getTileAt(tileIndex).sameVisTile(cts.getTileAt(tileIndex))) { return(false); } } return(true); } }
// [SC] gets the combo with the second highest score private void boardPosPermTraverseTreePaths(TreeNode rootNode, List <AbstractPos> currPath, CandidateTileSeq candTileSeq, int currScore , List <CandidateTilePos> chosenPosComboList, List <CandidateTilePos> maxScorePosCombo) { if (rootNode.hasChildNodes()) { List <TreeNode> childNodes = rootNode.getChildNodes(); foreach (TreeNode childNode in childNodes) { List <AbstractPos> newPath = currPath.listShallowClone(); AbstractPos pos = (AbstractPos)childNode.getValue(); newPath.Add(pos); boardPosPermTraverseTreePaths(childNode, newPath, candTileSeq, currScore + pos.getScore(), chosenPosComboList, maxScorePosCombo); } } else // [SC] reached the final leaf; no more moves in the combo { if (currScore > 0) { CandidateTilePos newCandTilePos = new CandidateTilePos(candTileSeq, currPath, currScore); if (maxScorePosCombo.Count == 0) { maxScorePosCombo.Add(newCandTilePos); chosenPosComboList.Clear(); chosenPosComboList.Add(newCandTilePos); } else if (maxScorePosCombo[0].getTotalScore() == currScore) { if (chosenPosComboList.Count != 0 && chosenPosComboList[0].getTotalScore() == currScore) { chosenPosComboList.Add(newCandTilePos); } } else if (maxScorePosCombo[0].getTotalScore() < currScore) { chosenPosComboList.Clear(); chosenPosComboList.Add(maxScorePosCombo[0]); maxScorePosCombo.Clear(); maxScorePosCombo.Add(newCandTilePos); } else if (maxScorePosCombo[0].getTotalScore() > currScore) { if (chosenPosComboList.Count == 0) { chosenPosComboList.Add(newCandTilePos); } else if (chosenPosComboList[0].getTotalScore() == maxScorePosCombo[0].getTotalScore()) { chosenPosComboList.Clear(); chosenPosComboList.Add(newCandTilePos); } else if (chosenPosComboList[0].getTotalScore() < currScore) { chosenPosComboList.Clear(); chosenPosComboList.Add(newCandTilePos); } else if (chosenPosComboList[0].getTotalScore() == currScore) { chosenPosComboList.Add(newCandTilePos); } } } } }