private bool DiagonalHasNoShotsLeft(int diagonal) { Coords curPos = new Coords(); for (int i = 0; i < 10; i++) { curPos = DiagonalToActual(diagonal, i); if (board[curPos.ColInt, curPos.RowInt] == TileType.Blank) { return false; } } return true; }
private Coords DiagonalToActual(int diag, int row) { Coords result = new Coords(); int effectiveXPosition = ((diag * 2) + diagonalsStart + row); result.RowInt = row; result.ColInt = effectiveXPosition % width; return result; }
public void SelectTarget(out char row, out int column) { switch(state) { case State.Searching: Coords pos = new Coords(); pos.RowInt = 0; pos.ColInt = 0; int diagonalPoint = rand.Next(10); pos = DiagonalToActual(currentDiagonal, diagonalPoint); List<int> validDiagonals = new List<int>(); for (int i = 0; i < 5; i++) { if (!DiagonalHasNoShotsLeft(i)) { validDiagonals.Add(i); } } if (validDiagonals.Count == 0) throw new ArgumentOutOfRangeException("No valid diagonals :("); currentDiagonal = validDiagonals[rand.Next(validDiagonals.Count)]; List<int> validRows = new List<int>(); Coords curPos = new Coords(); for (int i = 0; i < 10; i++) { curPos = DiagonalToActual(currentDiagonal, i); if (board[curPos.ColInt, curPos.RowInt] == TileType.Blank) { validRows.Add(i); } } if (validRows.Count == 0) throw new Exception("No valid rows somehow :("); // Select the row with the highest score assigned to it int currentRow = 0; int score = 0; int maxScore = 0; foreach (int r in validRows) { score = tileScores[currentDiagonal, r]; if (score == 0) throw new IndexOutOfRangeException("Score was zero :S"); if (score > maxScore) { maxScore = score; currentRow = r; } } //currentRow = validRows[rand.Next(validRows.Count)]; pos = DiagonalToActual(currentDiagonal, currentRow); row = pos.Row; column = pos.Col; lastShotSearching.Col = column; lastShotSearching.Row = row; lastShot.Col = column; lastShot.Row = row; shotCount++; timeSinceLastHit++; break; case State.Tracking: // Temporary row = 'A'; column = 1; // The shot to be made Coords shot = new Coords(); // Use a roulette wheel approach to select a direction to shoot in int shotDirection = rand.Next(32); // 32 seems a nice enough number to randomise with int roulettePos = rand.Next(4); // Choose a random starting position to minimise bias while (shotDirection > 0) { roulettePos = (roulettePos + 1) % 4; if (shotDirections[roulettePos] != -1) { shotDirection--; } } // Temporary (rubbish) fix for bad selections: // TODO: Just use this instead? while (shotDirections[roulettePos] == -1) { roulettePos = rand.Next(4); } // Check it hasn't picked a silly direction somehow if (shotDirections[roulettePos] == -1) { throw new Exception("Roulette wheel selection failed."); } // Make the shot lastTrackingShotDirection = (Direction)roulettePos; shotDirections[roulettePos]++; switch (lastTrackingShotDirection) { case Direction.Right: shot.RowInt = firstHitLocation.RowInt; shot.ColInt = (firstHitLocation.ColInt + shotDirections[(int)Direction.Right]) % height; break; case Direction.Up: shot.RowInt = (firstHitLocation.RowInt - shotDirections[(int)Direction.Up]) % width; shot.ColInt = firstHitLocation.ColInt; break; case Direction.Left: shot.RowInt = firstHitLocation.RowInt; shot.ColInt = (firstHitLocation.ColInt - shotDirections[(int)Direction.Left]) % width; break; case Direction.Down: shot.RowInt = (firstHitLocation.RowInt + shotDirections[(int)Direction.Down]) % height; shot.ColInt = firstHitLocation.ColInt; break; } if (shot.RowInt < 0) // C# mod doesn't wrap negatives :O { shot.RowInt = width + shot.RowInt; } if (shot.ColInt < 0) { shot.ColInt = height + shot.ColInt; } row = shot.Row; column = shot.Col; lastShot.Row = row; lastShot.Col = column; break; default: row = 'A'; column = 1; break; } }