/**
* Weak AI
*
* User: Pascal
* Version: 0.1
* Date: 13.04.13
*
* Changes:
* 0.1 (15.04.13)
* - First implementation
*/
package entities.artificialIntelligence;
import entities.Map.FieldMap;
import entities.ship.Ship;
import other.Randomizer;
import java.awt.Point;
import java.util.List;
import java.util.ArrayList;
/**
* Weak AI
*
* @author Pascal
* @version 0.1
*/
public class HardAI extends ArtificialIntelligence
{
enum Direction
{
Top,
Left,
Right,
Bottom,
None
}
enum Balance
{
Horizontal,
Vertical,
None
}
List<Point> lastHit;
List<Point> moves;
boolean shipSunk;
Direction direction;
boolean end;
/**
* Calculate missile
*
* @return Returns missile point.
*/
@Override
public Point DoWork(FieldMap map)
{
shipSunk = false;
Point ret = new Point(Randomizer.nextInt(Map.MapSize.x -1), Randomizer.nextInt(Map.MapSize.y -1));
// Get the direction where the target flow.
if (map.getHasHit())
{
lastHit.add(map.getHitPoint());
direction = Direction.Top;
}
if (map.getLastSunkenShip() != null)
{
shipSunk = true;
direction = Direction.None;
lastHit = new ArrayList<Point>();
end = false;
}
switch (getBalance())
{
// if the ai hit two parts of a ship, it can calculate the balancing
case Horizontal:
if (end)
ret.setLocation(moves.get(moves.size()-1).x, moves.get(moves.size()-1).y - 1);
else
{
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y + 1);
// Go to the other side if there is no more ship and it is not sunk yet.
if (!lastHit.get(lastHit.size() -1).equals(moves.get(moves.size()-1)))
end = true;
}
break;
case Vertical:
if (end)
ret.setLocation(moves.get(moves.size()-1).x + 1, moves.get(moves.size()-1).y);
else
{
ret.setLocation(lastHit.get(lastHit.size()-1).x - 1, lastHit.get(lastHit.size()-1).y);
// Go to the other side if there is no more ship and it is not sunk yet.
if (!lastHit.get(lastHit.size() -1).equals(moves.get(moves.size()-1)))
end = true;
}
break;
default:
// If the ai hi a target search all places around it for the next target.
switch (direction)
{
case Top:
if (lastHit.get(lastHit.size()-1).y < 1)
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y);
else
ret.setLocation(lastHit.get(lastHit.size()-1).x - 1, lastHit.get(lastHit.size()-1).y);
direction = Direction.Right;
break;
case Right:
if (lastHit.get(lastHit.size()-1).x == map.MapSize.y)
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y);
else
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y + 1);
direction = Direction.Bottom;
break;
case Bottom:
if (lastHit.get(lastHit.size()-1).y == map.MapSize.y)
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y);
else
ret.setLocation(lastHit.get(lastHit.size()-1).x + 1, lastHit.get(lastHit.size()-1).y);
direction = Direction.Left;
break;
case Left:
if (lastHit.get(lastHit.size()-1).x < 1)
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y);
else
ret.setLocation(lastHit.get(lastHit.size()-1).x, lastHit.get(lastHit.size()-1).y - 1);
direction = Direction.Top;
break;
default:
ret.setLocation(Randomizer.nextInt(Map.MapSize.x -1), Randomizer.nextInt(Map.MapSize.y -1));
break;
}
break;
}
if (other.Const.DEBUG)
System.out.println(end);
moves.add(ret);
return ret;
}
/**
* Get the direction of a ship
* @return Return vertical, horizontal or none if there is no balancing.
*/
private Balance getBalance()
{
if (lastHit.size() < 2 )
return Balance.None;
int i = lastHit.size()-1;
if (lastHit.get(i).x == lastHit.get(i-1).x)
return Balance.Horizontal;
else if (lastHit.get(i).y == lastHit.get(i-1).y)
return Balance.Vertical;
else
return Balance.None;
}
/**
* Determine the state of the ai and generate state sentence
*
* @return Returns strings with states of the ai (winning, loosing, etc.)
*/
@Override
public String GetState() {
String ret;
List<String> winSentences = new ArrayList<String>();
List<String> looseSentences = new ArrayList<String>();
List<String> normalSentences = new ArrayList<String>();
winSentences.add("I'm the best. :P");
winSentences.add("I thought I am winning.");
winSentences.add("Are you blind? ^^");
winSentences.add("There's nothing better than me, except Chuck.");
winSentences.add("Boring. :|");
winSentences.add("Problem?");
normalSentences.add("Do you know, the game exists more than 100 years.");
normalSentences.add("You're a good player.");
normalSentences.add("Hmmm.");
normalSentences.add("Lol.");
looseSentences.add("A bad game, I'm not winning.");
looseSentences.add("What, you're better than me. O.o");
looseSentences.add("This cannot be.");
if (Map.getMoves() == 0)
{
ret = "Let the game begin.";
}
else if (Map.getHasHit())
{
ret = normalSentences.get(Randomizer.nextInt(normalSentences.size() -1));
}
else if (Map.Defeated())
{
ret = looseSentences.get(Randomizer.nextInt(looseSentences.size() -1));
}
else
{
int sunkShips = 0;
for (Ship ship : Map.ships)
if (ship.IsSunk())
sunkShips++;
if (sunkShips > 8)
ret = looseSentences.get(Randomizer.nextInt(looseSentences.size() -1));
else if (sunkShips < 8)
ret = winSentences.get(Randomizer.nextInt(winSentences.size() -1));
else
ret = normalSentences.get(Randomizer.nextInt(normalSentences.size() -1));
}
return ret;
}
/**
* Set the ships of the ai.
*/
@Override
public void SetShips() {
Map.SetShipsRandomly();
}
/**
* Initialize the entity.
*/
@Override
public void Initialize() {
direction = Direction.None;
lastHit = new ArrayList<Point>();
moves = new ArrayList<Point>();
Map = new FieldMap();
}
/**
* Update the entity object.
*/
@Override
public void Update() {
Map.Update();
}
/**
* Dispose the class and release objects.
*/
@Override
public void Dispose() {
Map.Dispose();
}
}