private float simulateTurnWith(Tuple <int, int> selectedVoterIndex, District selectedDistrict) { List <District> tempDistrictList = new List <District> (gl.districtList); for (int i = 0; i < gl.districtList.Count; i++) { tempDistrictList[i] = District.copyFrom(gl.districtList[i]); } VoterGrid tempVotergrid = VoterGrid.copyFrom(gl.voterGrid); addVoterToDistrict(selectedVoterIndex, selectedDistrict.index, tempDistrictList, tempVotergrid); if (tempVotergrid.freeVoterSet.Count > 0) { Move enemyMove = selectMove(tempDistrictList, tempVotergrid, (player.index + 1) % 2); addVoterToDistrict(enemyMove.voterIndex, enemyMove.district.index, tempDistrictList, tempVotergrid); if (tempVotergrid.freeVoterSet.Count > 0) { Move myMove = selectMove(tempDistrictList, tempVotergrid, player.index); return(myMove.score); } else { return(1 - enemyMove.score); } } else { return((float)0.5); } }
private float scoreThisMove(Tuple <int, int> selVoterIndex, int selDistrict, List <District> districtList, VoterGrid voterGrid, int playerIndex, int depth) { // 1. Copy game situation: List <District> tempDistrictList = new List <District> (districtList); for (int i = 0; i < districtList.Count; i++) { tempDistrictList[i] = District.copyFrom(districtList[i]); } VoterGrid tempVotergrid = VoterGrid.copyFrom(voterGrid); float score; // score /elem [0,1], 0 = worst Score. // 2. Simulate Move: addVoterToDistrict(selVoterIndex, selDistrict, tempDistrictList, tempVotergrid); if (playerIndex == player.index && depth < this.targetDepth) { // 3. Select Best Enemy Move: Move enemyMove = findBestMove(tempDistrictList, tempVotergrid, (playerIndex + 1) % 2, depth, "My Move is: (" + selVoterIndex.First + "," + selVoterIndex.Second + ", " + selDistrict + ")"); // 4. Simulate best Enemy Move: addVoterToDistrict(enemyMove.voterIndex, enemyMove.district.index, tempDistrictList, tempVotergrid); // 5. Select best own Move: Move ownMove = findBestMove(tempDistrictList, tempVotergrid, playerIndex, depth); score = ownMove.score; } else { // 3. Score this situation for the player score = scoreSituation(tempDistrictList, tempVotergrid, playerIndex); } return(score); }
// Start of actual game here. void Start() { System.Random rnd = new System.Random(); gs = GameObject.Find("Initialize").GetComponent <GameSettings> (); playerList = gs.playerList; activePlayer = playerList[1]; //rnd.Next(2)]; for (int i = 0; i < 2; i++) { GameObject.Find("Player" + i + "Image" + 0).GetComponent <Image> ().sprite = playerList[i].sprite; GameObject.Find("Player" + i + "Image" + 1).GetComponent <Image> ().sprite = playerList[i].sprite; if (!playerList[i].isHuman && i == 0) { playerList[i].ai = new GerryAI(this, playerList[i]); } else if (!playerList[i].isHuman) { playerList[i].ai = new AI2(this, playerList[i]); this.refrenceAI = new GerryAI(this, playerList[i]); } } endPanel = GameObject.Find("EndPanel"); endPanel.SetActive(false); x = gs.x; ratio = gs.ratio; GameObject.Destroy(GameObject.Find("Initialize")); voterGrid = new VoterGrid(); voterGrid.initialize(); districtList = new List <District> (); float size = GameResources.Instance.sprite_size * x; GameObject.Find("Main Camera").GetComponent <ZoomScript>().zoomTo(size); for (int index = 0; index < GameResources.Instance.numberOfDistricts; index++) { GameObject button = GameObject.Find("DistrictButton" + index); GameObject textBox0 = GameObject.Find("P" + 0 + "Score" + index); GameObject textBox1 = GameObject.Find("P" + 1 + "Score" + index); button.SetActive(true); districtList.Add(new District(index, textBox0, textBox1, GameResources.Instance.colorList[index], this)); button.GetComponent <Image>().color = GameResources.Instance.colorList [index]; } activeDistrict = 0; activeColor = GameObject.Find("ActiveColor").GetComponent <Image> (); activateDistrict(0); for (int i = 0; i < 5; i++) { voterDistrictPlayer0.Add(GameObject.Find("1DistrictText" + i)); voterDistrictPlayer0 [i].SetActive(false); voterDistrictPlayer1.Add(GameObject.Find("2DistrictText" + i)); voterDistrictPlayer1 [i].SetActive(false); } advanceTurn(); }
private Move selectMove(List <District> districtList, VoterGrid voterGrid, int playerIndex) { //Select turn for opponent bool freeDistrictDone = false; float bestScore = 0; District bestDistrict = null; Tuple <int, int> bestVoterIndex = null; List <float> scoreList = new List <float>(); foreach (var district in districtList) { if (district.voterList.Count > 0) { foreach (var neighborindex in district.neighborSet) { float score = simulateSecondTurnWith(districtList, voterGrid, neighborindex, district.index, playerIndex); scoreList.Add(score); if (score >= bestScore) { bestScore = score; bestDistrict = district; bestVoterIndex = neighborindex; } } } else if (!freeDistrictDone) { foreach (var voterIndex in voterGrid.freeVoterSet) { float score = simulateSecondTurnWith(districtList, voterGrid, voterIndex, district.index, playerIndex); scoreList.Add(score); if (score >= bestScore) { bestScore = score; bestDistrict = district; bestVoterIndex = voterIndex; } } freeDistrictDone = true; } } if (bestDistrict == null) { Debug.LogError("No possible move for Player" + playerIndex); foreach (var score in scoreList) { Debug.Log(score); } } return(new Move(bestDistrict, bestVoterIndex, bestScore)); }
private float simulateSecondTurnWith(List <District> districtList, VoterGrid voterGrid, Tuple <int, int> selectedVoterIndex, int selectedDistrict, int playerIndex) { List <District> tempDistrictList = new List <District> (districtList); for (int i = 0; i < districtList.Count; i++) { tempDistrictList[i] = District.copyFrom(districtList[i]); } VoterGrid tempVotergrid = VoterGrid.copyFrom(voterGrid); addVoterToDistrict(selectedVoterIndex, selectedDistrict, tempDistrictList, tempVotergrid); return(score(tempDistrictList, tempVotergrid, playerIndex)); }
public static VoterGrid copyFrom(VoterGrid old) { VoterGrid copy = new VoterGrid(); copy.array = old.array.Clone() as Voter[, ]; for (int i = 0; i < old.x; i++) { for (int j = 0; j < old.x; j++) { copy.array [i, j] = Voter.copyFrom(old.array[i, j]); } } copy.x = old.x; copy.freeVoterSet = new HashSet <Tuple <int, int> >(old.freeVoterSet); return(copy); }
public override Move findBestMove(List <District> districtList, VoterGrid voterGrid, int playerIndex, int depth, String logString = "") { float bestScore = 0; District bestDistrict = null; Tuple <int, int> bestVoterIndex = null; bool freeDistrictDone = false; foreach (var district in gl.districtList) { if (district.voterList.Count > 0) { foreach (var neighborindex in district.neighborSet) { float score = simulateTurnWith(neighborindex, district); if (score >= bestScore) { bestScore = score; bestDistrict = district; bestVoterIndex = neighborindex; } } } else if (!freeDistrictDone) { foreach (var voterIndex in gl.voterGrid.freeVoterSet) { float score = simulateTurnWith(voterIndex, district); if (score >= bestScore) { bestScore = score; bestDistrict = district; bestVoterIndex = voterIndex; } } freeDistrictDone = true; } } return(new Move(bestDistrict, bestVoterIndex, bestScore)); }
public override Move findBestMove(List <District> districtList, VoterGrid voterGrid, int playerIndex, int depth, String logString = "") { Move bestMove = new Move(null, null, 0); bool freeSetDone = false; HashSet <Tuple <int, int> > voterIndexSet; // Do loop over possible districts foreach (var district in gl.districtList) { if (district.voterList.Count > 0) { voterIndexSet = district.neighborSet; } else { voterIndexSet = gl.voterGrid.freeVoterSet; } if (!freeSetDone || district.voterList.Count > 0) { foreach (var voterIndex in voterIndexSet) { float score = scoreThisMove(voterIndex, district.index, districtList, voterGrid, playerIndex, depth + 1); if (score >= bestMove.score) { bestMove = new Move(district, voterIndex, score); } } } if (district.voterList.Count == 0) { freeSetDone = true; } } //if (logString != "") Debug.Log(logString); //Debug.Log("Best move at depth "+ depth + " for player " + playerIndex + " is (" + bestMove.voterIndex.First + "," + bestMove.voterIndex.Second + ", " + bestMove.district.index + ") with score " + bestMove.score); return(bestMove); }
private void addVoterToDistrict(Tuple <int, int> voterIndex, int district, List <District> districtList, VoterGrid voterGrid) { voterGrid.array[voterIndex.First, voterIndex.Second].district = district; districtList[district].voterList.Add(voterIndex); voterGrid.freeVoterSet.Remove(voterIndex); List <Voter> neighbors = voterGrid.getNeighbors(voterGrid.array[voterIndex.First, voterIndex.Second]); foreach (var neighbor in neighbors) { if (neighbor.district == -1) { districtList[district].neighborSet.Add(Tuple.New(neighbor.col, neighbor.row)); } else { districtList[neighbor.district].neighborSet.Remove(voterIndex); } } }
private float score(List <District> districtList, VoterGrid votergrid, int playerIndex) { float[] score = new float[2] { 0f, 0f }; int neighborCountSum = 0; float neighborCountSqrdSum = 0; foreach (var district in districtList) { int[] districtCounter = new int[2] { 0, 0 }; foreach (var voterIndex in district.voterList) { districtCounter[votergrid.array[voterIndex.First, voterIndex.Second].player.index]++; } int[] neighborCounter = new int[2] { 0, 0 }; foreach (var neighborIndex in district.neighborSet) { neighborCounter[votergrid.array[neighborIndex.First, neighborIndex.Second].player.index]++; } int diff = districtCounter[0] - districtCounter[1]; int totalNeighbors = neighborCounter[0] + neighborCounter[1]; //player 0 float distScore; if (diff >= 1) { distScore = 1 - probability(totalNeighbors, neighborCounter[1], diff); } else { distScore = (float)0.1 * probability(totalNeighbors, neighborCounter[0], -diff + 1); } score[0] += distScore; if (distScore < -1) { Debug.Log("First distScore: " + distScore); } //player 1 if (diff <= -1) { distScore = 1 - probability(totalNeighbors, neighborCounter[0], -diff); } else { distScore = (float)0.1 * probability(totalNeighbors, neighborCounter[1], diff + 1); } score[1] += distScore; if (distScore < -1) { Debug.Log("Second distScore: " + distScore); } neighborCountSum += district.neighborSet.Count; neighborCountSqrdSum += Mathf.Pow(district.neighborSet.Count, 2); } int[] freeCounter = new int[2] { 0, 0 }; if (votergrid.freeVoterSet.Count > 0) { foreach (var voterIndex in votergrid.freeVoterSet) { freeCounter[votergrid.array[voterIndex.First, voterIndex.Second].player.index]++; } float freePercentageP0 = (float)freeCounter[0] / (freeCounter[0] + freeCounter[1]); score[0] += freePercentageP0 * Mathf.Pow(neighborCountSum, 2) / neighborCountSqrdSum; score[1] += (1 - freePercentageP0) * Mathf.Pow(neighborCountSum, 2) / neighborCountSqrdSum; } return(score[playerIndex] / (score[playerIndex] + score[(playerIndex + 1) % 2])); }
public abstract Move findBestMove(List <District> districtList, VoterGrid voterGrid, int playerIndex, int depth, String logString = "");