2015-03-31 7 views
1

Итак, у меня есть playerID и numwalls для каждого игрока в настольной игре, которую я делаю. Прямо сейчас, чтобы удалить стены, когда каждый игрок использует один, каждый в основном разделяет стены.Как уменьшить значение в HashMap?

Итак, я решил, что должен сделать hashmap в качестве ключа playerID и numwalls.

Но я не знаю, как уменьшить значение ключей, когда предполагается использовать стену.

Я покажу свой код, который имеет проблему.

public int getWallsRemaining(int i) { 
    return numWalls; 
} 

public void lastMove(PlayerMove playerMove) { 
    System.out.println("in lastMove... " + playerMove); 
    /** 
    * if piece moves, update its position 
    */ 
    if(playerMove.isMove() == true){ 

     Integer player = playerMove.getPlayerId(); 

     Coordinate newLoc = new Coordinate(playerMove.getEndRow(), playerMove.getEndCol()); 
     playerHomes.put(player, newLoc); 

    } 
    /** 
    * if a wall is placed, subtract the wall form the player who placed it 
    * and subtract the appropriate neighbors. 
    */ 
    if(playerMove.isMove() == false){ 
     numWalls-=1; 
     removeNeighbor(playerMove.getStart(), playerMove.getEnd()); 

    } 


} 

Вот где я инициализировать все, walls моя карта для того, что я пытаюсь сделать:

private Map<Coordinate, HashSet<Coordinate>> graph; 

private int PlayerID; 
private int numWalls; 
private Map<Integer, Coordinate> playerHomes; 
private Map<Integer, Integer> walls; 



@Override 
public void init(Logger logger, int playerID, int numWalls, Map<Integer, Coordinate> playerHomes) { 


    this.PlayerID = playerID; 
    this.walls = new HashMap<Integer, Integer>(); 
    this.numWalls = numWalls; 
    this.playerHomes = playerHomes; 
    this.graph = new HashMap<Coordinate, HashSet<Coordinate>>(); 
    walls.put(playerID,numWalls); 

    for(int r = 0; r <= 10; r++){ 
     for(int c = 0; c <= 10; c++){ 
      HashSet<Coordinate> neighbors = new HashSet<Coordinate>(); 
       if(r > 0){ 
        neighbors.add(new Coordinate(r - 1, c)); 
       } 
       if(r < 8){ 
        neighbors.add(new Coordinate(r + 1, c)); 
       } 
       if(c > 0){ 
        neighbors.add(new Coordinate(r, c - 1)); 
       } 
       if(c < 8){ 
        neighbors.add(new Coordinate(r, c + 1)); 
       } 
      graph.put((new Coordinate(r,c)), neighbors); 
     } 
    } 
} 

Вы можете увидеть в моем методе lastMove, что я декремента стены на 1. Это мой проблема. Я хочу уменьшить указанный playerIDnumwall на 1. Что у меня теперь работает только для 1 игрока. Мне нужно это для работы до 4 игроков.

ответ

2

A HashMap может содержать только объекты (не примитивы), поэтому вы должны вставить значение Integer в качестве отображаемого значения.

Integer Поскольку непреложный класс вы не можете напрямую изменить значение, необходимо заменить его, отбрасывая старое значение, что-то вроде:

HashMap<Player, Integer> walls = new HashMap<Player,Integer>(); 

int currentWalls = walls.get(player); 
walls.put(player, currentWalls-1); 
+0

Этот код должен (возможно) быть синхронизирован. Или используйте [AtomicInteger] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html) в качестве значения. – user949300

0

Для изменения значения сохраняются с помощью ключа вы следует удалить старое значение и добавить новое значение.

Как вы считаете, считаете ли вы создание класса Player для инкапсуляции playerId и количества стен, которые имеет игрок? Это может работать лучше для ваших планов.

1

Я бы использовал AtomicInteger, чтобы сохранить ваши значения. Это потокобезопасно, в случае одновременного использования нескольких игроков в стенах. И это проще, чем воссоздавать новую Integer каждый раз (как в @Jack ответ)

HashMap<Player, AtomicInteger> walls = new HashMap<Player,AtomicInteger>(); 

... 

walls.get(player).decrementAndGet(); 

В случае необходимости, вы можете вернуть значение из decrementAndGet() для получения нового номера стен.

+0

Привет, спасибо за ваш ответ. Теперь у меня это работает, используя карту ключа Integer и значений, но ваша идея AtomicInteger интересна и нова для меня. Поэтому я создал цикл в моем init, чтобы заполнить карту моей стены, но когда я делаю walls.put (i, numwalls), я получаю сообщение об ошибке в numWalls, говоря, что для этого требуется AtomicInteger, а не Integer. Я немного смущен, но мне нравится ваша идея. – FatFockFrank

+0

Java будет «autobox» int целым, но не AtomicInteger. В вашем цикле зайдите 'walls.put (theKey, новый AtomicInteger (numwalls));' – user949300

Смежные вопросы